非同期型ソケット関数を使用したTCPクライアントのサンプルプログラムです。

 接続先のアクセスポイントはシステムメニューで設定してください。
 TCPサーバーのIPアドレスは、ソースコード上で指定してください。

動作概要

  1. [ENT]キーを押すと無線LANを有効にします。
  2. アクセスポイントに接続したら、TCPクライアント自身のIPアドレスを表示します。
  3. TCPクライアントはTCPサーバーに接続を要求します。 (ConnectSc関数)
  4. TCPサーバーに接続すると、"OPH-5000i<CR>"を送信します。(SendSc関数)
  5. TCPサーバーへの送信に成功すると、受信を開始します。(RecvSc関数)
  6. TCPサーバーからのデータを受信すると、ソケットを切断します。(CloseSc関数)
  7. TCPクライアント動作を終了し、無線LANを無効にし、1.に戻ります。

サンプル
#include <stdio.h>
#include <string.h>
#include "lib.h"
#include "logapi.h"

#define CONNECT_IP          "192.168.11.100"
#define SEND_MESSAGE        "OPH-5000i\n"
#define CONNECT_PORT        20080
#define TCPCL_BUFFER_MAX    1500
#define LOG_TCPSV 1

enum
{
    TCPCL_STATE_INIT = 0,
    TCPCL_STATE_CONNECT,
    TCPCL_STATE_CONNECTED,
};
enum
{
    TCP_RECV_STATE_INIT = 0,
    TCP_RECV_STATE_READY,
    TCP_RECV_STATE_RECEIVED,
};
enum
{
    TCP_SEND_STATE_INIT = 0,
    TCP_SEND_STATE_READY,
    TCP_SEND_STATE_SENDING,
    TCP_SEND_STATE_SENT,
};
static unsigned char recvBuffer[TCPCL_BUFFER_MAX];
static unsigned char sendBuffer[TCPCL_BUFFER_MAX];
static short recvSize;
static short sendSize;
static short sendResult = 0;
static SOCKET peerSocket;
static unsigned char tcpclState;
static unsigned char recvState;
static unsigned char sendState;
static unsigned char requestReset;

static void TcpClInit(void)
{
    recvSize = 0;
    peerSocket = -1;
    tcpclState = TCPCL_STATE_INIT;
    recvState = TCP_RECV_STATE_INIT;
    sendState = TCP_SEND_STATE_INIT;
    requestReset = FALSE;
    memset(recvBuffer, 0, sizeof(recvBuffer));
}
static void socket_cb(SOCKET sock, unsigned char u8Msg, void *pvMsg)
{
    if (sock == peerSocket){
        switch (u8Msg){
        case SOCKET_MSG_CONNECT:
            if (pvMsg != NULL){
                tstrSocketConnectMsg *pstrConnect = (tstrSocketConnectMsg *)pvMsg;
                LOG_PRINTF(LOG_TCPSV, "SOCKET_MSG_CONNECT sock=%d conect sock=%d s8Error=%d", sock, pstrConnect->sock, pstrConnect->s8Error);
                if (sock == pstrConnect->sock && pstrConnect->s8Error == SOCK_ERR_NO_ERROR){
                    tcpclState = TCPCL_STATE_CONNECTED;
                    sendState = TCP_SEND_STATE_READY;
                    memset(recvBuffer, 0, sizeof(recvBuffer));
                    recvSize = 0;
                }else{
                    CloseSc(peerSocket);
                    peerSocket = -1;
                    requestReset = TRUE;
                }
            }
            break;
        case SOCKET_MSG_SEND:
            if (pvMsg != NULL){
                sendResult = *(short *)pvMsg;
                LOG_PRINTF(LOG_TCPSV, "SOCKET_MSG_SEND sock=%d length=%d", sendResult);
                if (sendResult <= 0){
                    CloseSc(peerSocket);
                    peerSocket = -1;
                    recvState = TCP_RECV_STATE_INIT;
                    sendState = TCP_SEND_STATE_INIT;
                }else{
                    sendState = TCP_SEND_STATE_SENT;
                }
            }
            break;
        case SOCKET_MSG_RECV:
            if (pvMsg != NULL){
                tstrSocketRecvMsg *pstrRecv = (tstrSocketRecvMsg *)pvMsg;
                LOG_PRINTF(LOG_TCPSV, "SOCKET_MSG_RECV sock=%d s16BufferSize=%d u16RemainingSize=%d pu8Buffer:%s",
                    sock, pstrRecv->s16BufferSize, pstrRecv->u16RemainingSize, pstrRecv->pu8Buffer);
                recvSize = pstrRecv->s16BufferSize;
                if (pstrRecv->s16BufferSize > (int)sizeof(recvBuffer) ||
                    pstrRecv->s16BufferSize <= 0){
                    CloseSc(peerSocket);
                    peerSocket = -1;
                    recvState = TCP_RECV_STATE_INIT;
                    sendState = TCP_SEND_STATE_INIT;
                }else{
                    recvState = TCP_RECV_STATE_RECEIVED;
                }
            }
            break;
        default:
            LOG_PRINTF(LOG_TCPSV, "sock=%d u8msg=%d pvMsg=0x%x", sock, u8Msg, pvMsg);
            break;
        }
    }
}

void main(void)
{
    char key;
    int wlanPowerState = OFF;
    int wlanConnect = SYS_WLAN_STATUS_UNAVAILABLE;
    int prevWlanConnect;
    long brText;
    tstrM2MConnInfo conInfo;
    unsigned char tcpsvPrevState;
    struct sockaddr_in addr;

    addr.sin_family = AF_INET;
    addr.sin_port = _htons(CONNECT_PORT);
    addr.sin_addr.s_addr = nmi_inet_addr(CONNECT_IP);
    memset(addr.sin_zero, 0, sizeof(addr.sin_zero));
    printf( "TCP CLIENT\n" );
    while (1){
        if (wlanPowerState == OFF){
            printf( "ENT to connect server\n" );
            SysSetWLANPower(SYS_WLAN_POWER_OFF);
            while (1){
                if (kbhit()){
                    if (getchar() == ENT_KEY){
                        wlanPowerState = ON;
                        break;
                    }
                }
                Idle();
            }
        }else{
            printf( "\fStart TCP client\n" );
            printf( "BS to end\n" );
            SysSetWLANPower(SYS_WLAN_POWER_AUTO);
            SysWLANInit(NULL);
            InitSc();
            TcpClInit();
            RegSocketCallbackSc(socket_cb, NULL);
            tcpsvPrevState = tcpclState;
            prevWlanConnect = SYS_WLAN_STATUS_UNAVAILABLE;
            while (1){
                if (requestReset == TRUE){
                    break;
                }
                if (kbhit()){
                    key = getchar();
                    if (key == BS_KEY){
                        wlanPowerState = OFF;
                        break;
                    }
                }
                while (1){
                    SysGetWLANConnectStatus(&wlanConnect);
                    if (wlanConnect == SYS_WLAN_STATUS_CONNECTED){
                        if (wlanConnect != prevWlanConnect){
                            if (SysGetConnectInfoWlan(&conInfo) == TRUE){
                                prevWlanConnect = wlanConnect;
                                printf("Wlan connected\nIP:%d.%d.%d.%d\n",
                                    conInfo.au8IPAddr[0], conInfo.au8IPAddr[1], conInfo.au8IPAddr[2], conInfo.au8IPAddr[3]);
                                LOG_PRINTF(LOG_TCPSV, "Wlan connected IP:%d.%d.%d.%d",
                                    conInfo.au8IPAddr[0], conInfo.au8IPAddr[1], conInfo.au8IPAddr[2], conInfo.au8IPAddr[3]);
                            }
                        }
                        break;
                    }
                    if (kbhit()){
                        if (getchar() == BS_KEY){
                            wlanPowerState = OFF;
                            break;
                        }
                    }
                    Idle();
                }
                if (tcpclState != tcpsvPrevState){
                    LOG_PRINTF(LOG_TCPSV, "State:%d", tcpclState);
                    tcpsvPrevState = tcpclState;
                    if (tcpclState == TCPCL_STATE_CONNECTED){
                        printf("Socket connected\n");
                        // Set send message --------------
                        strcpy(sendBuffer, SEND_MESSAGE);
                        sendSize = strlen(SEND_MESSAGE);
                        // -------------------------------
                    }
                }
                if (peerSocket < 0){
                    if ((peerSocket = SocketSc(AF_INET, SOCK_STREAM, 0)) < 0){
                        requestReset = TRUE;
                        continue;
                    }
                    if (ConnectSc(peerSocket, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) != SOCK_ERR_NO_ERROR){
                        requestReset = TRUE;
                        continue;
                    }
                    tcpclState = TCPCL_STATE_CONNECT;
                }
                if (recvState == TCP_RECV_STATE_RECEIVED && recvSize > 0){
                    LOG_PRINTF(LOG_TCPSV, "recv:%s", recvBuffer);
                    // Show receive data
                    brText = SetTextColor(RGB_RED);
                    printf("%s", recvBuffer);
                    SetTextColor(brText);
                    // Clear receive buffer
                    memset(recvBuffer, 0, sizeof(recvBuffer));
                    recvSize = 0;
                    // TCP client End ----------------
                    printf("Socket close\n");
                    CloseSc(peerSocket);
                    wlanPowerState = OFF;
                    break;
                    // -------------------------------
                }
                if (sendState == TCP_SEND_STATE_READY){
                    if (sendSize > 0){
                        // Send message
                        if (SendSc(peerSocket, sendBuffer, sendSize, 0) != SOCK_ERR_NO_ERROR){
                            requestReset = TRUE;
                            sendSize = 0;
                            continue;
                        }
                        LOG_PRINTF(LOG_TCPSV, "send:%s", sendBuffer);
                        // Show send data
                        brText = SetTextColor(RGB_BLUE);
                        printf("%s", sendBuffer);
                        SetTextColor(brText);
                        // Clear send buffer
                        memset(sendBuffer, 0, sizeof(sendBuffer));
                        sendSize = 0;
                        sendState = TCP_SEND_STATE_SENDING;
                    }
                }else if (sendState == TCP_SEND_STATE_SENT){
                    // Start receive -----------------
                    if (RecvSc(peerSocket, recvBuffer, sizeof(recvBuffer), 0) != SOCK_ERR_NO_ERROR){
                        requestReset = TRUE;
                    }else{
                        recvState = TCP_RECV_STATE_READY;
                    }
                    // -------------------------------
                }
                Idle();
            }
        }
        Idle();
    }
}

最終更新日:2020/12/20