2016-10-21 15 views
0

私は2つのプログラムを接続するソケットプログラムを作っています。 Winsockのセットアップ、接続と対話。ただし、クライアント側からサーバー側に送信されるファイルには、奇妙な文字が含まれています。奇妙なファイル出力ソケットファイル転送

例:

File: test.txt 
Contents: Hey, how are you? 
** Client sends file over to Server ** 
Expected Output: Hey, how are you? 
Actual Output: 7_ Ä _ 

Serverコード:

int main() { 
    WSADATA Winsock; 
    SOCKET Socket, Sub; 
    Addr addr; 
    IncomingAddress incomingAddress; 
    int AddressLen = sizeof(IncomingAddress); 

    // Start up Winsock 
    WSAStartup(MAKEWORD(2, 2), &Winsock); 

    if (LOBYTE(Winsock.wVersion) != 2 || HIBYTE(Winsock.wVersion) != 2) { 
     WSACleanup(); 
     return 0; 
    } 

    Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 

    // Memset alternative 
    ZeroMemory(&addr, sizeof(Addr)); 
    addr.sin_family = AF_INET; 
    addr.sin_port = htons(portNumber); 
    bind(Socket, (sockaddr*) &addr, sizeof(Addr)); 

    if (listen(Socket, 1) == SOCKET_ERROR) { 
     printf("Listening error!\n"); 
    } else { 
     printf("Listening...\n"); 
    } 

    if (Sub = accept(Socket, (sockaddr*) &incomingAddress, &AddressLen)) { 
     int Size; 
    char *Filesize = malloc(MAX_PATH); 

    if (recv(Socket, Filesize, MAX_PATH, 0)) { // File Size 
     Size = atoi((const char*) Filesize); 
     printf("File size: %d\n", Size); 
    } 

    char *Buffer = malloc(Size); 

    int Offset = 0; 
    while (Size > Offset) { 
     printf("TESST"); 
     int Amount = recv(Socket, Buffer + Offset, Size - Offset, 0); 

     if (Amount <= 0) { 
      printf("Error: " + WSAGetLastError()); 
      break; 
     } else { 
      Offset += Amount; 
     } 
    } 

    FILE *File; 
    File = fopen("test.txt", "wb+"); 
    fwrite(Buffer, 1, Size, File); 
    fclose(File); 

    getchar(); 
    closesocket(Socket); 
    WSACleanup(); 

    } 
} 
return 0; 
} 

クライアントコード:

int main() { 
    WSADATA Winsock; 
    SOCKET Socket, Sub; 
    Addr addr; 
    IncomingAddress incomingAddress; 
    int AddressLen = sizeof(IncomingAddress); 

    WSAStartup(MAKEWORD(2, 2), &Winsock); 

    if (LOBYTE(Winsock.wVersion) != 2 || HIBYTE(Winsock.wVersion) != 2) { 
     WSACleanup(); 
     return 0; 
    } 

    Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 

    ZeroMemory(&addr, sizeof(Addr)); 
    addr.sin_family = AF_INET; 
    addr.sin_addr.s_addr = inet_addr("127.0.0.1"); 
    addr.sin_port = htons(6000); 

    if (connect(Socket, (sockaddr*) &addr, sizeof(Addr)) < 0) { 
     printf("Connection Failed!\n"); 
     getchar(); 
     return 0; 
    } 

     char *ClientIP = inet_ntoa(incomingAddress.sin_addr); 
     int ClientPort = ntohs(incomingAddress.sin_port); 
     printf("Client connected!\n"); 
     printf("IP: %s:%d\n", ClientIP, ClientPort); 

     printf("Sending file... \n"); 

     FILE *File; 
     char *Buffer; 
     unsigned long Size; 

     File = fopen("test.txt", "rb+"); 
     if (!File) { 
      printf("Error while reading the file!\n"); 
      getchar(); 
      return 0; 
     } 

     fseek(File, 0, SEEK_END); 
     Size = ftell(File); 
     fseek(File, 0, SEEK_SET); 

     Buffer = malloc(Size); 

     fread(Buffer, Size, 1, File); 
     char cSize[MAX_PATH]; 
     sprintf(cSize, "%i", Size); 

     fclose(File); 
     send(socket, cSize, MAX_PATH, 0); // File size 

     int Offset = 0; 
     while (Size > Offset) { 
      int Amount = send(Sub, Buffer + Offset, Size - Offset, 0); 

      if (Amount <= 0) { 
       printf("Error: " + WSAGetLastError()); 
       break; 
      } else { 
       Offset += Amount; 
      } 
     } 
     free(Buffer); 
     closesocket(Sub); 
     closesocket(Socket); 
     WSACleanup(); 
     printf("File sent!\n"); 
    return 0; 
} 

答えて

1

あなたは三つの問題、クライアントに1つ、サーバーに2つを持っています。

クライアントでは、ファイルのサイズをSocketで送信していますが、これは正しいです。しかし、接続されていない初期化されていないソケットSubを使用して、ファイルのデータを送信します。

サーバーでは、許容接続ソケットSubの代わりにパッシブリスニングsocketを使用してサイズとデータの両方を受信しようとすると、ほぼ反対の問題が発生します。

また、サーバーでは、データを読み取るときにエラーが発生した場合はレポートしますが、それでもファイルにデータを書き込みます。この場合、未知の長さの未初期化データとなります。

正しいソケットを使用してください。エラーがある場合は、しないでください。

そして実際にはする何らかのエラーチェック。サーバのサイズを受け取ったときには、接続のもう一方の端で接続が閉じられていないというエラーをチェックしません。

+0

私はそこで何が間違っているかを見ます。ありがとうございました。あなたは非常に知識があります。 :) – Josh