2017-04-08 10 views
0

私は、Windows上のサーバーとクライアントの間のTCPソケットを介して双方向通信をしようとしています。私はスレッドを使用しようとしましたが、うまくいきません。理由はわかりません。WINDOWS C:TCPソケットsend&recv同時に。

whileループに入れようとすると、次のメッセージを印刷する前にユーザーが何かを入力するのを待ちます(fgets()のため)。スレッドと

while(1) { 
     bzero(message, 2000); 
     if (recv(sock, message, 2000, 0) < 0) { 
      printf("Connection lost!\n"); 
      getch(); 
     } 
     else { 
      strcat(message, "\0"); 
      fprintf(stdout, "%s", message); 
     }; 
     bzero(client, 2000); 

     fgets(sednmesg, sizeof(sednmesg), stdin); 
     strcat(client, sednmesg); 
     strcat(client, "\0"); 
     send(sock, client, strlen(client), 0); 
} 

私の悲惨な試み:

Server.c:

#include <stdio.h> 
#include <winsock.h> 
#include <stdlib.h> 
#include "stdafx.h" 
#include <conio.h> 
#include <io.h> 

#define bzero(b,len) (memset((b), '\0', (len)), (void) 0) 

#pragma comment(lib,"ws2_32.lib") //Winsock Library 

char message[4040]; 

DWORD WINAPI thrd() { 
    WSADATA wsa; 
    SOCKET sock, newsock; 
    int c; 
    struct sockaddr_in server, client; 
    char smesg[155]; 
    printf("\nInitialising Winsock..."); 
    if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) 
    { 
     printf("Failed. Error Code : %d", WSAGetLastError()); 
     return 1; 
    } 

    printf("Initialised.\n"); 

    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) { 
     printf("Could not create socket! Error: %d", WSAGetLastError()); 
     return 1; 
    } 
    //textcolor(2); 
    printf("Socket Created!\n"); 

    server.sin_family = AF_INET; 
    server.sin_addr.s_addr = INADDR_ANY; 
    server.sin_port = htons(8989); 

    //bind 
    if (bind(sock, (struct sockaddr *)&server, sizeof(server)) == SOCKET_ERROR) { 
     printf("Bind failed! Error Code: %d", WSAGetLastError()); 
    } 
    puts("Binded!"); 
    printf("\nNow Listening...\n"); 
    listen(sock, 1); 
    //Accept! 
    c = sizeof(struct sockaddr_in); 
    newsock = accept(sock, (struct sockaddr *)&client, &c); 
    if (newsock == INVALID_SOCKET) { 
     printf("Couldn't Accept connection!"); 
    } 

    printf("Accepted Connection!\n"); 
    u_long iMode = 1; 
    ioctlsocket(newsock, FIONBIO, &iMode); 
    Sleep(99); 
    system("cls"); 
    printf("Writer Thread has been started!"); 
    //char *client_ip = inet_ntoa(client.sin_addr); 
    //int client_port = ntohs(client.sin_port); 
    while (1) { 
     bzero(smesg, sizeof(smesg)); 
     fgets(smesg, sizeof(smesg), stdin); 
     strcat(smesg, "\0"); 
     send(newsock, smesg, strlen(smesg), 0); 
    } 
} 

int main() 
{ 
    WSADATA wsa; 
    FILE * fp; 
    unsigned long on = 1; 
    const char *file = "fout.txt"; 
    SOCKET sock, newsock; 
    int c; 
    struct sockaddr_in server, client; 
    char smesg[155]; 
    printf("\nInitialising Winsock..."); 
    if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) 
    { 
     printf("Failed. Error Code : %d", WSAGetLastError()); 
     return 1; 
    } 

    printf("Initialised.\n"); 

    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) { 
     printf("Could not create socket! Error: %d", WSAGetLastError()); 
     return 1; 
    } 
    //textcolor(2); 
    printf("Socket Created!\n"); 

    server.sin_family = AF_INET; 
    server.sin_addr.s_addr = INADDR_ANY; 
    server.sin_port = htons(3939); 

    //bind 
    if (bind(sock, (struct sockaddr *)&server, sizeof(server)) == SOCKET_ERROR) { 
     printf("Bind failed! Error Code: %d", WSAGetLastError()); 
    } 
    puts("Binded!"); 
    printf("\nNow Listening...\n"); 
    listen(sock, 1); 
    //Accept! 
    c = sizeof(struct sockaddr_in); 
    newsock = accept(sock, (struct sockaddr *)&client, &c); 
    ioctlsocket(newsock, FIONBIO, &on); 
    if (newsock == INVALID_SOCKET) { 
     printf("Couldn't Accept connection!"); 
    } 

    printf("Accepted Connection!\n"); 
     //char *client_ip = inet_ntoa(client.sin_addr); 
     //int client_port = ntohs(client.sin_port); 
    HANDLE thread = CreateThread(NULL, 0, thrd, NULL, 0, NULL); 
    fp = fopen(file, "r+"); 
     while (1) { 
      /* 
      bzero(smesg, sizeof(smesg)); 
      printf("Command: "); 
      fgets(smesg, 155, stdin); 
      strcat(smesg, "\0"); 
      send(newsock, smesg, strlen(smesg), 0); 
      */ 
      bzero(message, sizeof(message)); 
      recv(newsock, message, 2000, 0); 
      fprintf(stdout, "%s", message); 
      fprintf(fp, "%s", message); 
     } 
     fclose(fp); 
    return 0; 
} 

いるclient.c:あなたは別の2を接続開く/する必要はありません

#include <stdio.h> 
#include <winsock.h> 
#include <stdlib.h> 
#include "stdafx.h" 
#include <conio.h> 

#define bzero(b,len) (memset((b), '\0', (len)), (void) 0) 

#pragma comment(lib,"ws2_32.lib") //Winsock Library 

DWORD WINAPI thrd() { 
    char client[2050] = "Client: "; 
    WSADATA wsa; 
    SOCKET sock; 
    struct sockaddr_in server; 
    char sednmesg[2000]; 
    printf("\nInitialising Winsock..."); 
    if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) 
    { 
     printf("Failed. Error Code : %d", WSAGetLastError()); 
     getch(); 
     return 1; 
    } 

    printf("Initialised.\n"); 


    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) { 
     printf("Could not create socket! Error: %d", WSAGetLastError()); 
     getch(); 
     return 1; 
    } 
    //textcolor(2); 
    printf("Socket Created!\n"); 
    //ioctlsocket(sock, FIONBIO, &on); 
    server.sin_addr.s_addr = inet_addr("127.0.0.1"); 
    server.sin_family = AF_INET; 
    server.sin_port = htons(8989); 

    //Connect 
    if (connect(sock, (struct sockaddr *)&server, sizeof(server)) < 0) { 
     puts("Connect Error"); 
     getch(); 
     return 1; 
    } 
    puts("Connected\n"); 
    // If iMode!=0, non-blocking mode is enabled. 
    u_long iMode = 1; 
    ioctlsocket(sock, FIONBIO, &iMode); 
    Sleep(99); 
    system("cls"); 
    printf("Writer Thread has been started!"); 
    //We'll be running this one on port 8989 if this doesn't work! 
    while (1) { 
     bzero(client, 2000); 
     fgets(sednmesg, sizeof(sednmesg), stdin); 
     strcat(client, sednmesg); 
     strcat(client, "\0"); 
     send(sock, client, strlen(client), 0); 
    } 
} 

int main(int argc, char *argv[]) 
{ 
    char *msg = "a"; 
    char client[2050] = "Client: "; 
    unsigned long on = 1; 
    int reader; 
    WSADATA wsa; 
    int sent = 0; 
    SOCKET sock; 
    struct sockaddr_in server; 
    char message[2000]; 
    char sednmesg[2000]; 
    printf("\nInitialising Winsock..."); 
    if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) 
    { 
     printf("Failed. Error Code : %d", WSAGetLastError()); 
     getch(); 
     return 1; 
    } 

    printf("Initialised.\n"); 


    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) { 
     printf("Could not create socket! Error: %d", WSAGetLastError()); 
     getch(); 
     return 1; 
    } 
    //textcolor(2); 
    printf("Socket Created!\n"); 
    //ioctlsocket(sock, FIONBIO, &on); 
    server.sin_addr.s_addr = inet_addr("127.0.0.1"); 
    server.sin_family = AF_INET; 
    server.sin_port = htons(3939); 

    //Connect 
    if (connect(sock, (struct sockaddr *)&server, sizeof(server)) < 0) { 
     puts("Connect Error"); 
     getch(); 
     return 1; 
    } 
    puts("Connected\n"); 
    // If iMode!=0, non-blocking mode is enabled. 
    u_long iMode = 1; 
    ioctlsocket(sock, FIONBIO, &iMode); 
    //Creating writer thread. 
    HANDLE thread = CreateThread(NULL, 0, thrd, NULL, 0, NULL); 
    while (1) { 
     bzero(message, 2000); 
     if (recv(sock, message, 2000, 0) < 0) { 
      printf("Connection lost!\n"); 
      getch(); 
     } 
     else { 
      strcat(message, "\0"); 
      fprintf(stdout, "%s", message); 
     }; 
     //bzero(client, 2000); 
     /* 
     fgets(sednmesg, sizeof(sednmesg), stdin); 
     strcat(client, sednmesg); 
     strcat(client, "\0"); 
     send(sock, client, strlen(client), 0); 
     */ 
    } 
    return 0; 
} 
+2

ウィットに:正しく完全にrecvによって返される結果を処理するために失敗したことを( )。 TCPのストリーミング性を許さない。 NULターミネータを必要とするC 'string'コールの誤用。カーゴカルトbzero()cycle-wasterの使用。 – ThingyWotsit

+1

サーバーが2つのリスニングポートを開き、クライアントが2つのリスニングポートに接続しているのはなぜですか?双方向通信に複数のポートは必要ありません。 –

答えて

0

双方向通信を実現するためにリスニングポートを使用します。 TCPは双方向で、1つの接続だけが必要です。ただし、両端で非ブロッキングソケットI/Oを有効にしていますが、実際には非ブロッキングI/Oを正しく使用しているわけではありません。特に、WSAEWOULDBLOCKエラーコードはまったく処理されていません。これは、読み取り可能なデータがない場合はrecv()、受信者があまりにも多くのデータを読み込み、新しいデータをまだ受信できない場合はsend()によって報告されます。

スレッドを使用する場合は、読み取りと送信に別々のスレッドを使用し、ノンブロッキングI/Oをすべて忘れてしまいます。しかし、スレッドを正しく定義していることを確認してください(スレッドプロシージャには必須の入力パラメータがありません!)。

より、このような何か試してみてください:

Server.c:

#include "stdafx.h" 
#include <stdio.h> 
#include <winsock.h> 
#include <stdlib.h> 
#include <conio.h> 

#pragma comment(lib,"ws2_32.lib") //Winsock Library 

DWORD WINAPI sendThrd(LPVOID lpParam) 
{ 
    SOCKET sock = * (SOCKET*) lpParam; 
    char smesg[155], *pdata; 
    int len, ret; 

    do 
    { 
     if (!fgets(smesg, sizeof(smesg), stdin)) 
      break; 

     len = strlen(smesg); 
     pdata = smesg; 

     while (len > 0) 
     { 
      ret = send(sock, pdata, len, 0); 
      if (ret == SOCKET_ERROR) 
      { 
       printf("Send failed. Error: %d", WSAGetLastError()); 
       break; 
      } 
      pdata += ret; 
      len -= ret; 
     } 
    } 
    while (true); 

    shutdown(sock, SD_SEND); 
    return 0; 
} 

DWORD WINAPI recvThrd(LPVOID lpParam) 
{ 
    SOCKET sock = * (SOCKET*) lpParam; 
    char smesg[256]; 
    int ret; 

    FILE *fp = fopen("fout.txt", "w+"); 

    do 
    { 
     ret = recv(sock, smesg, sizeof(smesg), 0); 
     if (ret <= 0) 
     { 
      if (ret == 0) 
       printf("Client disconnected\n"); 
      else 
       printf("Connection lost! Error: %d\n", WSAGetLastError()); 
      break; 
     } 

     printf("%.*s", ret, smesg); 

     if (fp) 
      fprintf(fp, "%.*s", ret, smesg);   
    } 
    while (true); 

    if (fp) 
     fclose(fp); 

    shutdown(sock, SD_RECEIVE); 
    return 0; 
} 

int main() 
{ 
    WSADATA wsa; 
    SOCKET sock, newsock; 
    int c; 
    struct sockaddr_in server; 

    printf("Initializing Winsock...\n"); 
    int ret = WSAStartup(MAKEWORD(2, 2), &wsa); 
    if (ret != 0) 
    { 
     printf("Initialization Failed. Error: %d", ret); 
     return 1; 
    } 
    printf("Initialized.\n"); 

    sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 
    if (sock == INVALID_SOCKET) { 
     printf("Could not create socket! Error: %d\n", WSAGetLastError()); 
     return 1; 
    } 
    //textcolor(2); 
    printf("Socket Created!\n"); 

    memset(&server, 0, sizeof(server)); 
    server.sin_family = AF_INET; 
    server.sin_addr.s_addr = INADDR_ANY; 
    server.sin_port = htons(3939); 

    //bind 
    if (bind(sock, (struct sockaddr *)&server, sizeof(server)) == SOCKET_ERROR) { 
     printf("Bind failed! Error: %d\n", WSAGetLastError()); 
     closesocket(sock); 
     return 1; 
    } 
    printf("Binded!\n"); 

    // listen 
    if (listen(sock, 1) == SOCKET_ERROR) { 
     printf("Listen failed! Error: %d\n", WSAGetLastError()); 
     closesocket(sock); 
     return 1; 
    } 
    printf("Now Listening...\n"); 

    //Accept! 
    c = sizeof(client); 
    newsock = accept(sock, (struct sockaddr *)&client, &c); 
    if (newsock == INVALID_SOCKET) { 
     printf("Couldn't Accept connection! Error: %d\n", WSAGetLastError()); 
     closesocket(sock); 
     return 1; 
    } 

    //char *client_ip = inet_ntoa(client.sin_addr); 
    //int client_port = ntohs(client.sin_port); 
    printf("Accepted Connection!\n"); 

    printf("Starting Reader/Writer Threads...\n"); 
    HANDLE threads[2]; 
    threads[0] = CreateThread(NULL, 0, sendThrd, &newsock, 0, NULL); 
    threads[1] = CreateThread(NULL, 0, recvThrd, &newsock, 0, NULL); 

    WaitForMultipleObjects(2, threads, TRUE, INFINITE); 

    CloseHandle(threads[0]); 
    CloseHandle(threads[1]); 

    closesocket(newsock); 
    closesocket(sock); 

    return 0; 
} 

いるclient.c:

#include "stdafx.h" 
#include <stdio.h> 
#include <winsock.h> 
#include <stdlib.h> 
#include <conio.h> 

#pragma comment(lib,"ws2_32.lib") //Winsock Library 

DWORD WINAPI sendThrd(LPVOID lpParam) 
{ 
    SOCKET sock = * (SOCKET*) lpParam; 
    char smesg[155], *pdata; 
    int len, ret; 

    do 
    { 
     if (!fgets(smesg, sizeof(smesg), stdin)) 
      break; 

     len = strlen(smesg); 
     pdata = smesg; 

     while (len > 0) 
     { 
      ret = send(sock, pdata, len, 0); 
      if (ret == SOCKET_ERROR) 
      { 
       printf("Send failed. Error: %d\n", WSAGetLastError()); 
       break; 
      } 
      pdata += ret; 
      len -= ret; 
     } 
    } 
    while (true); 

    shutdown(sock, SD_SEND); 
    return 0; 
} 

DWORD WINAPI recvThrd(LPVOID lpParam) 
{ 
    SOCKET sock = * (SOCKET*) lpParam; 
    char smesg[256]; 
    int ret; 

    do 
    { 
     ret = recv(sock, smesg, sizeof(smesg), 0); 
     if (ret <= 0) 
     { 
      if (ret == 0) 
       printf("Server disconnected\n"); 
      else 
       printf("Connection lost! Error: %d\n", WSAGetLastError()); 
      break; 
     } 

     printf("%.*s", ret, smesg); 
    } 
    while (true); 

    shutdown(sock, SD_RECEIVE); 
    return 0; 
} 

int main(int argc, char *argv[]) 
{ 
    WSADATA wsa; 
    SOCKET sock; 
    struct sockaddr_in server; 

    printf("Initializing Winsock...\n"); 
    int ret = WSAStartup(MAKEWORD(2, 2), &wsa); 
    if (ret != 0) 
    { 
     printf("Initialization Failed. Error: %d", ret); 
     return 1; 
    } 
    printf("Initialized.\n"); 

    sock = socket(AF_INET, SOCK_STREAM, 0); 
    if (sock == INVALID_SOCKET) { 
     printf("Could not create socket! Error: %d", WSAGetLastError()); 
     getch(); 
     return 1; 
    } 
    //textcolor(2); 
    printf("Socket Created!\n"); 

    memset(&server, 0, sizeof(server)); 
    server.sin_addr.s_addr = inet_addr("127.0.0.1"); 
    server.sin_family = AF_INET; 
    server.sin_port = htons(3939); 

    //Connect 
    if (connect(sock, (struct sockaddr *)&server, sizeof(server)) == SOCKET_ERROR) { 
     printf("Connect failed! Error: %d", WSAGetLastError()); 
     closesocket(sock); 
     getch(); 
     return 1; 
    } 
    printf("Connected\n"); 

    //Creating reader/writer threads. 

    printf("Starting Reader/Writer Threads...\n"); 
    HANDLE threads[2]; 
    threads[0] = CreateThread(NULL, 0, sendThrd, &sock, 0, NULL); 
    threads[1] = CreateThread(NULL, 0, recvThrd, &sock, 0, NULL); 

    WaitForMultipleObjects(2, threads, TRUE, INFINITE); 

    CloseHandle(threads[0]); 
    CloseHandle(threads[1]); 

    closesocket(sock); 

    getch(); 
    return 0; 
} 
関連する問題