2016-08-01 4 views
0

これは現在のコードです。複数のクライアントを同時に処理できるようにスレッドを導入しようとしていますが、これを行う方法を理解するのはちょっと困っています。どんな助けもありがとう。Winsock - スレッドで複数のクライアントを許可する

クライアント:

int create_client() 
{ 

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; 

// Initialize Winsock 
iResult = WSAStartup(MAKEWORD(2,2), &wsaData); 
if (iResult != 0) { 
    printf("WSAStartup failed with error: %d\n", iResult); 
    return 1; 
} 

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

// Resolve the server address and port 
iResult = getaddrinfo(DEFAULT_IP, DEFAULT_PORT, &hints, &result); 
if (iResult != 0) { 
    printf("getaddrinfo failed with error: %d\n", iResult); 
    WSACleanup(); 
    return 1; 
} 

// Attempt to connect to an address until one succeeds 
for(ptr=result; ptr != NULL ;ptr=ptr->ai_next) { 

    // Create a SOCKET for connecting to server 
    ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, 
     ptr->ai_protocol); 
    if (ConnectSocket == INVALID_SOCKET) { 
     printf("socket failed with error: %ld\n", WSAGetLastError()); 
     WSACleanup(); 
     return 1; 
    } 

    // Connect to server. 
    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; 
} 

// Send an initial buffer 
iResult = send(ConnectSocket, sendbuf, (int)strlen(sendbuf), 0); 
if (iResult == SOCKET_ERROR) { 
    printf("send failed with error: %d\n", WSAGetLastError()); 
    closesocket(ConnectSocket); 
    WSACleanup(); 
    return 1; 
} 

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

// shutdown the connection since no more data will be sent 
iResult = shutdown(ConnectSocket, SD_SEND); 
if (iResult == SOCKET_ERROR) { 
    printf("shutdown failed with error: %d\n", WSAGetLastError()); 
    closesocket(ConnectSocket); 
    WSACleanup(); 
    return 1; 
} 

// Receive until the peer closes the connection 
do { 

    iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0); 
    if (iResult > 0) 
     printf("Bytes received: %d\n", iResult); 
    else if (iResult == 0) 
     printf("Connection closed\n"); 
    else 
     printf("recv failed with error: %d\n", WSAGetLastError()); 

} while(iResult > 0); 

// cleanup 
closesocket(ConnectSocket); 
WSACleanup(); 

return 0; 
} 

サーバー:

WSADATA wsaData; 
int iResult; 

SOCKET ListenSocket = INVALID_SOCKET; 
SOCKET ClientSocket = INVALID_SOCKET; 

struct addrinfo *result = NULL; 
struct addrinfo hints; 

int iSendResult; 
char recvbuf[DEFAULT_BUFLEN]; 
int recvbuflen = DEFAULT_BUFLEN; 

// Initialize Winsock 
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData); 
if (iResult != 0) { 
    printf("WSAStartup failed with error: %d\n", iResult); 
    return 1; 
} 

ZeroMemory(&hints, sizeof(hints)); 
hints.ai_family = AF_INET; 
hints.ai_socktype = SOCK_STREAM; 
hints.ai_protocol = IPPROTO_TCP; 
hints.ai_flags = AI_PASSIVE; 

// Resolve the server address and port 
iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result); 
if (iResult != 0) { 
    printf("getaddrinfo failed with error: %d\n", iResult); 
    WSACleanup(); 
    return 1; 
} 

// Create a SOCKET for connecting to server 
ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol); 
if (ListenSocket == INVALID_SOCKET) { 
    printf("socket failed with error: %ld\n", WSAGetLastError()); 
    freeaddrinfo(result); 
    WSACleanup(); 
    return 1; 
} 

// Setup the TCP listening socket 
iResult = bind(ListenSocket, result->ai_addr, (int)result->ai_addrlen); 
if (iResult == SOCKET_ERROR) { 
    printf("bind failed with error: %d\n", WSAGetLastError()); 
    freeaddrinfo(result); 
    closesocket(ListenSocket); 
    WSACleanup(); 
    return 1; 
} 

freeaddrinfo(result); 

iResult = listen(ListenSocket, SOMAXCONN); 
if (iResult == SOCKET_ERROR) { 
    printf("listen failed with error: %d\n", WSAGetLastError()); 
    closesocket(ListenSocket); 
    WSACleanup(); 
    return 1; 
} 

cout << "Server initalized." << endl; 

// Accept a client socket 
ClientSocket = accept(ListenSocket, NULL, NULL); 
if (ClientSocket == INVALID_SOCKET) { 
    printf("accept failed with error: %d\n", WSAGetLastError()); 
    closesocket(ListenSocket); 
    WSACleanup(); 
    return 1; 
} 

// No longer need server socket 
closesocket(ListenSocket); 

// Receive until the peer shuts down the connection 
do { 

    iResult = recv(ClientSocket, recvbuf, recvbuflen, 0); 
    if (iResult > 0) { 
     printf("Bytes received: %d\n", iResult); 

     // Echo the buffer back to the sender 
     iSendResult = send(ClientSocket, recvbuf, iResult, 0); 
     if (iSendResult == SOCKET_ERROR) { 
      printf("send failed with error: %d\n", WSAGetLastError()); 
      closesocket(ClientSocket); 
      WSACleanup(); 
      return 1; 
     } 
     printf("Bytes sent: %d\n", iSendResult); 
    } else if (iResult == 0) 
     printf("Connection closing...\n"); 
    else { 
     printf("recv failed with error: %d\n", WSAGetLastError()); 
     closesocket(ClientSocket); 
     WSACleanup(); 
     return 1; 
    } 

} while (iResult > 0); 

// shutdown the connection since we're done 
iResult = shutdown(ClientSocket, SD_SEND); 
if (iResult == SOCKET_ERROR) { 
    printf("shutdown failed with error: %d\n", WSAGetLastError()); 
    closesocket(ClientSocket); 
    WSACleanup(); 
    return 1; 
} 

// cleanup 
closesocket(ClientSocket); 
WSACleanup(); 

return 0; 
} 
+0

エラーメッセージはありますか? – Takarii

答えて

0

あなたはリスニングと処理部分を分離する必要があります。

したがって、メインスレッドはソケットを聴き、いくつかの接続を受け取ると3つのスレッドを作成します。

スレッドは接続にクライアントソケット、読み取りと処理を許可します。あなたのメインスレッドの

擬似コード:あなたのスレッドの

while (true){ 
    listen the socket 
    if any entry connection{ 
     create thread and process the petition 
    } 
} 

擬似コード:

accept connection and obtain the client socket 
process it 
close the client socket 

EDIT: PD:これは一時的な解決策を持っている任意の現実の状況では、巨額の請願はうまくいかないでしょう。

+0

ありがとう、私はそれを働かせた!実際の生活の状況では、代わりに何が行われるだろうか?私はあなたが効率的ではないxクライアントを処理する非常に多くのスレッドを持つことを意味すると仮定します。 – Taliyah

+0

私は効率的な方法を使って実際の経験を持っていませんが、これはあなたがそれについてアイデアを持つのを助けることができると思う、http://vichargrave.com/multithreaded-work-queue-based-server-2/ 別のアイデア嘆願の「プール」を持つことができますし、使い分け可能なスレッドの使用のバランスを取るために効率的な方法を使用し、プールからスレッドに「仕事」を渡して結果を収集することができます。 – Raskayu

関連する問題