2010-01-20 35 views
0

該代碼完美地發送和接收txt文件,但不能將其用於.exe或.img等格式。請幫助我,因爲我需要使用htonl或htons? 看一看!用於在一個字符串中獲取while緩衝區的recv()函數標誌[windows C]

這裏是服務器端recv函數::

if (socket_type != SOCK_DGRAM) 
     { 

       fi = fopen (final,"wb"); 
       retval = recv(msgsock, recv_buf, strlen(recv_buf), 0); 
       /*recv_buf[retval] = '\0'; 
       fprintf (fi,"%s",recv_buf);*/ 

       int i; 
       i=atoi(recv_buf); 
       char *q; 
       q=(char *)malloc(i*sizeof(char)); 
       retval = recv(msgsock, q, strlen(q), 0); 
       //printf ("%s",q); 
       fwrite(q,i,1,fi); 
       fclose(fi); 

     } 
     else 
     { 
      retval = recvfrom(msgsock,recv_buf, sizeof(recv_buf), 0, (struct sockaddr *)&from, &fromlen); 
      printf("Server: Received datagram from %s\n", inet_ntoa(from.sin_addr)); 
      printf ("SOCK_DGRAM"); 
     } 

     if (retval == SOCKET_ERROR) 
     { 
      fprintf(stderr,"Server: recv() failed: error %d\n", WSAGetLastError()); 
      closesocket(msgsock); 
      //continue; 
     } 
     else 
      printf("Server: recv() is OK.\n"); 

     if (retval == 0) 
     { 
      printf("Server: Client closed connection.\n"); 
      closesocket(msgsock); 
       //continue; 
     } 
     printf("Server: Received %d bytes, data from client\n", retval); 

The client side sending function ::: 

void send_command() 
{ 
    int bytesent; 
    FILE *file_out; 
    //file_out = fopen(file_path,"rb"); 
    char str_all[100000];//flag [30]="end"; 

    ///////////////////////getsize////////////// 
    char fsize[5]; 
    int filesize; 
    file_out = fopen(file_path, "rb"); 
    fseek(file_out, 0, SEEK_END); 
    filesize = ftell(file_out); 
    rewind (file_out); 
    itoa (filesize,fsize,10); 
    ///////////////////////////////////////////// 
    send (ConnectSocket, fsize, strlen (fsize), 0); 

    char *r = (char *)malloc (filesize * sizeof(char)); 

    fread(r,filesize,1,file_out); 
    bytesent = send(ConnectSocket, r, strlen(r), 0); 
    printf("\nClient: Bytes sent: %ld\n", bytesent); 
    fclose (file_out); 

    /*while (fscanf(file_out,"%s",&str_all) != EOF) 
    { 
     bytesent = send(ConnectSocket, str_all, strlen(str_all), 0); 
     printf("\nClient: Bytes sent: %ld\n", bytesent); 
     //Sleep(500); 
    }*/ 

    /*printf("%s",flag); 
    send(ConnectSocket, flag, strlen(flag), 0);*/ 
    WSACleanup(); 
    //return 0; 
    } 

回答

2

好的,您的程序有多個問題。

  • 您正在傳輸二進制數據。接收器只會看到一個字節序列。接收器無法知道數據的結尾,因爲char的所有可能值都是合法的數據值。如果您要發送文本數據,則可以說0表示數據已結束,但現在您不能。所以,你必須決定服務器和客戶端之間的「協議」,最簡單的是服務器在前4個字節中發送數據的長度(在ntonl()ntohl()上閱讀,瞭解如何移動)。然後,接收器將確切知道要讀取多少個字節。
  • 您將接收緩衝區聲明爲char *recv_buf,對recv_buf1也同樣如此。您不會爲任何兩個指針分配任何存儲空間,因此它們不會指向任何有用的地方。那麼,你的recv電話是:recv(msgsock, recv_buf, sizeof(recv_buf), 0);這也有問題。第一個是上面提到的:你沒有recv_buf的存儲空間。第二個是做完之後爲recv_buf分配存儲空間,你取的是字符指針的大小而不是指向緩衝區的長度recv。解決這兩個問題的一個簡單方法是將recv_buf聲明爲:char recv_buf[SIZE];,然後在recv()調用中使用sizeof recv_buf

我還沒有看過你的其他代碼。您可能需要一個很好的C和網絡編程介紹。

+0

分配是我發現的一個問題,但我真的很喜歡這個,現在學習它像2周。 htons是我在想但不能實現的解決方案。感謝你的回答!! – 2010-01-21 08:28:32

+0

如果分配是一個問題,您可以像我說的那樣使用一個數組,但從長遠來看,您應該學習C中的指針和malloc以及朋友。對於聯網,有許多好的在線教程,或者您可以閱讀Stevens的書。 – 2010-01-21 08:32:50

1

我想你混淆C字符串與插座上發送一個數據包結束的空終止。沒有數據包的「終止」,它只是一串字節。零點是完全合法的,並且你明確地傳遞(並接收)了長度。您當然不需要使用帶外設備來接收多個數據包。你能更具體地說明你在問什麼嗎?

+0

我想發送一個像.mp3或任何格式的文件,然後將它保存並保存爲.mp3。所以雙方必須同時發送和recv!當我發送文本文件時,服務器端只會收到SPACE或ENTER(/ n)前的長度。所以我需要發送一個文件。問題出在服務器端,因爲它不能同時接收。 – 2010-01-20 22:30:01

+2

我沒跟着。我認爲你需要退出並閱讀一些關於套接字編程的教程。史蒂文斯的Unix網絡編程是一本經典的書,但有很多可用的網頁內容。 – 2010-01-20 22:32:36

相關問題