完全なるクライアントコード
更新日2006年10月03日
参照 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/complete_client_code.asp

以下は、TCP/IPクライアントアプリケーションのための完全なソースコードです。

クライアントソースコード[complete_client_code.lzh]

/*
 * file:complete_client_code.c
 * 完全なるクライアントコード
 * 参照 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/complete_client_code.asp
 */
#define _WIN32_WINNT 0x0501
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <stdlib.h>

#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT "27015"

int main(int argc, char *argv[])
{
    WSADATA wsaData;
    SOCKET ConnectSocket = INVALID_SOCKET;
    struct addrinfo *result = NULL,
                    *ptr = NULL,
                    hints;
    char *sendbuf = "this is a test";
    char recvbuf[DEFAULT_BUFLEN];
    int iResult;
    int recvbuflen = DEFAULT_BUFLEN;
    
    /*
     * パラメタを確認
     */
    if (argc != 2)
    {
        printf("usage: %s server-name\n", argv[0]);
        return 1;
    }

    /*
     * Winsockを初期化
     */
    iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
    if (iResult != 0)
    {
        printf("WSAStartup failed: %d\n", iResult);
        return 1;
    }

    ZeroMemory(&hints, sizeof(hints));
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    /*
     * サーバアドレスとポートを分解
     */
    iResult = getaddrinfo(argv[1], DEFAULT_PORT, &hints, &result);
    if (iResult != 0)
    {
        printf("getaddrinfo failed: %d\n", iResult);
        WSACleanup();
        return 1;
    }

    /*
     * 成功するまでアドレスに接続を試みます
     */
    for (ptr = result; ptr != NULL; ptr = ptr->ai_next)
    {
        /*
         * サーバへ接続をするためにSOCKETを作成
         */
        ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, 
                ptr->ai_protocol);
        if (ConnectSocket == INVALID_SOCKET)
        {
            printf("Error at socket(): %ld\n", WSAGetLastError());
            freeaddrinfo(result);
            WSACleanup();
            return 1;
        }

        /*
         * サーバへ接続
         */
        iResult = connect(ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
        if (iResult == SOCKET_ERROR)
        {
            closesocket(ConnectSocket);
            ConnectSocket = INVALID_SOCKET;
            continue;
        }
        break;
    }

    freeaddrinfo(result);

    if (ConnectSocket == INVALID_SOCKET)
    {
        printf("Unable to connect to server!\n");
        WSACleanup();
        return 1;
    }

    /*
     * 最初のバッファを送信
     */
    iResult = send(ConnectSocket, sendbuf, (int)strlen(sendbuf), 0);
    if (iResult == SOCKET_ERROR)
    {
        printf("send failed: %d\n", WSAGetLastError());
        closesocket(ConnectSocket);
        WSACleanup();
        return 1;
    }

    printf("Bytes Sent: %ld\n", iResult);

    /*
     * 送信データがそれ以上ないなら、接続をシャットダウン
     */
    iResult = shutdown(ConnectSocket, SD_SEND);
    if (iResult == SOCKET_ERROR)
    {
        printf("shutdown failed: %d\n", WSAGetLastError());
        closesocket(ConnectSocket);
        WSACleanup();
        return 1;
    }

    /*
     * 接続先が接続を閉じるまで、繰り返し受信する
     */
    do
    {
        ZeroMemory(recvbuf, recvbuflen);
        iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
        if (0 < iResult)
        {
            printf("Bytes received: %d\n", iResult);
            printf("recieved data: [%s]\n", recvbuf);
        }
        else if (iResult == 0)
        {
            printf("Connection closed\n");
        }
        else
        {
            printf("recv failed: %d\n", WSAGetLastError());
        }
    } while (0 < iResult);

    /*
     * クリーンアップ
     */
    closesocket(ConnectSocket);
    WSACleanup();

    return 0;
}