2017-09-05 23 views
0

我在C套接字中運行問題。 有一臺服務器,有一個客戶端。有服務器發送大量的數據給客戶端。當我按CTRL + C終止客戶端時,我重新啓動服務器(1,關閉套接字fd,2,再次構建套接字fd)。 但是當我再次運行客戶端時,它從上次連接中收到大量數據。我猜數據在服務器發送緩衝區中。當我最後一次關閉客戶端時,那裏仍然有數據。 有什麼方法可以清除數據? 感謝當重新連接到服務器時,C套接字客戶端接收大量數據

示例代碼

void socket_server_init(unsigned short port) 

    { 

    struct sockaddr_in serverAddress; 
    struct sockaddr_in clientAddress; 

    if((serverSocket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))<0){ 
     printf("create socket error??"); 
     exit(-1); 
    } 

    memset(&serverAddress,0,sizeof(serverAddress)); 
    serverAddress.sin_family=AF_INET; 
    serverAddress.sin_addr.s_addr = htonl(INADDR_ANY); 
    serverAddress.sin_port = htons(port); 


    int optval = -1; 
    socklen_t optlen = -1; 
    optval = 1; 
    optlen = sizeof(optval); 
    setsockopt(serverSocket, SOL_SOCKET, SO_REUSEADDR, &optval, optlen); 


    if(bind(serverSocket,(struct sockaddr*)&serverAddress,sizeof(serverAddress))<0) 
{ 
     printf("bind socket to port failed??port: %d\n",port); 
     exit(-1); 
    } 

    if(listen(serverSocket,SOMAXCONN)<0){ 
     printf("listen failed!\n"); 
     exit(-1); 
    } 
    printf("Server %d is listening......\n",port); 
    memset(&clientAddress,0,sizeof(clientAddress)); 
    int addrlen = sizeof(clientAddress); 
    if((clientSocket=accept(serverSocket,(struct sockaddr*)&clientAddress,&addrlen))<0){ 
     printf("accept client connection failed??\n"); 
     exit(-1); 
    } 
    return; 
} 
void stop_sever(void) 
{ 
    server_status = SOCKET_STATUS_INIT; 
    send_mode = SOCKET_SENDING_MODE_NORMAL; 
    send_flag = 0; 
    pc_transfer_mode = 0;//1 normal //2 through 
    Image_transfer_status = SERVER_STATUS_STOP_IMAGE; 
    Pre_Image_transfer_status = SERVER_STATUS_STOP_IMAGE; 
    data_received_once = 0; 

} 

void reset_server(void) 
{ 
    printf("reset servern"); 
    stop_sever(); 
    printf("Close server socket\n"); 
    //close(clientSocket); 
    //shutdown(clientSocket, SHUT_RDWR); 
    close(serverSocket); 
    printf("shutdown server socket\n"); 
    shutdown(serverSocket, SHUT_RDWR); 
    //shutdown(serverSocket_alert, SHUT_RDWR); 
    printf("restart server socket\n"); 
    socket_server_init(port); 
    //socket_server_init_alert(8001); 
} 

void send_image(unsigned char *virt_addr_to_display, unsigned char cmd, unsigned char res) 
{ 
    printf("[display] Entering: %s,,, %p\n", __FUNCTION__, virt_addr_to_display); 
    int i = 0; 
    int len = 0; 
    if(cmd == SERVER_STATUS_TRANSFER_1) 
    { 
     if(res == IMAGE_RESOLUTION_1280X720) 
     { 
      len = FRAME_SIZE_1; 
     } 
     else if(res == IMAGE_RESOLUTION_640X480) 
     { 
      len = PHONE_FRAME_SIZE_1; 
     } 
     else//error 
     { 
      len = FRAME_SIZE_1; 
      printf("Error\n"); 
     } 
    } 
    else if(cmd == SERVER_STATUS_TRANSFER_2) 
    { 
     if(res == IMAGE_RESOLUTION_1280X720) 
     { 
      len = FRAME_SIZE_2; 
     } 
     else if(res == IMAGE_RESOLUTION_640X480) 
     { 
      len = PHONE_FRAME_SIZE_2; 
     } 
     else//error 
     { 
      len = FRAME_SIZE_2; 
      printf("Error\n"); 
     } 
    } 
    else if(cmd == SERVER_STATUS_TRANSFER_3) 
    { 
     if(res == IMAGE_RESOLUTION_1280X720) 
     { 
      len = FRAME_SIZE_2; 
     } 
     else if(res == IMAGE_RESOLUTION_640X480) 
     { 
      len = PHONE_FRAME_SIZE_2; 
     } 
     else//error 
     { 
      len = FRAME_SIZE_2; 
      printf("Error SERVER_STATUS_TRANSFER_3\n"); 
     } 
    } 
    else 
    { 
     printf("here error\n"); 
     //return; 
    } 
    printf("len %d\n", len); 

    int cur_len; 
    while(len > 0) 
    { 
     cur_len = (len > DATA_PACKET_SIZE) ? DATA_PACKET_SIZE : len; 
     if(send(clientSocket, virt_addr_to_display, cur_len,0)<0) 

     { 
      printf("send Image Data failed??\n"); 
      reset_server(); 
      break; 
     } 
     len -= cur_len; 
     virt_addr_to_display += cur_len; 
    } 
    printf("[display] After send, len = %d\n ",len); 
    return; 
} 

int main(int argc, char **argv) 
{ 



    status = STATUS_START; 


    socket_server_init(port); 


    pthread_t cmd_t; 
    pthread_create(&cmd_t, NULL, (void*)cmd_process, NULL); 
    int ret; 
    ret = signal(SIGPIPE,sig_pipe); 
    if(SIG_ERR == ret) 
    { 
     printf("sig pipe error \n"); 
     return -1; 
    } 
    else 
    { 
     printf("signal pipe succeed\n") ; 
    } 

    char *client_buf; 
    client_buf = (char*)malloc(sizeof(client_cmd)); 


    while(1) 

    { 

     if(status == STATUS_START) 
     { 

      if(((get_send_flag() == 1)||(Image_transfer_status != SERVER_STATUS_STOP_IMAGE))||(pc_transfer_mode != 0)) 
      { 
       set_send_flag(0); 
       int send_ret; 

       send_ret = send(clientSocket, (const char*)&server_cmd, sizeof(server_cmd), 0); 
       if(send_ret< 0) //Server send head packet to client. 
       { 
        printf("Server send head packet fail!\n"); 
        reset_server(); 
        break; 

       } 
       printf("Image_transfer_status != 0, send finished\n"); 
       //see if send cmd 
       static unsigned int i = 0; 
       { 

        { 
         static int cnt = 0; 
         if(pc_transfer_mode == 1) 
         { 
          printf("Send 1\n"); 
          send_image(buf_right + (i%30)*FRAME_SIZE_2, SERVER_STATUS_TRANSFER_3, server_cmd.res); 
          printf("Send 2\n"); 
          send_image(buf_disparity + (i%30)*FRAME_SIZE_1, SERVER_STATUS_TRANSFER_1, server_cmd.res); 

          i++; 
         } 
         else if(pc_transfer_mode == 2) 
         { 
          printf("Send 1\n"); 
          send_image(buf_right + (i%30)*FRAME_SIZE_2, SERVER_STATUS_TRANSFER_3, server_cmd.res); 
          printf("Send 2\n"); 
          send_image(buf_left + (i%30)*FRAME_SIZE_2, SERVER_STATUS_TRANSFER_2, server_cmd.res); 
          i++; 
         } 
         else 
         { 

         } 
         printf("Image %d\n", cnt%30); 
         cnt++; 
        } 
       } 
      } 
      usleep(10000); 

     } 

    } 
    return 0; 
} 
+0

順便說一句,我正在使用TCP –

+0

請問您可以發佈您的代碼? – Jabberwock

+0

添加示例代碼 –

回答

0

據我瞭解,你在做這樣的事情在你的服務器代碼:

int srv; 
srv = socket(srv,...); 
//(...) 
bind(srv,...); 
//(...) 
listen(srv,...); 
//(...) 

int fd; 
char message[BUFSIZE]; 
//accept any client connection and build a specific socket for it 
while(true){ 
    fd = accept(srv,...); 
    //(...) 
    int len = read(fd,message,BUFSIZE); 
    //(...) 
    //closing the connection to that client once the task is over 
    close(fd); 
} 
close(srv); 

如果是那樣的話,你應該清除緩衝區message之前執行read()

一個簡單的方法來做到這一點是使用memset(),這樣的代碼,這部分應該是這樣的:

//(...) 
memset(message,'0',BUFSIZE); 
int len = read(fd,message,BUFSIZE); 
//(...) 
+0

您的意思是服務器上次收到數據並在客戶端重新連接時重新發送給客戶端? –

+0

讀過你的代碼後,它看起來像你使用的唯一緩衝區是'client_buf',你可以在其上創建一個malloc並且永遠不會重置它。 當處於該'while'塊時,可能會發生以前的數據保存在該內存位置和後續的客戶端連接中,服務器發回該數據的副本。 我建議你在新連接之後使用'memset',甚至是'calloc'而不是'malloc'來開始,以便分配的內存已經被初始化並清除了可能存在的任何垃圾。 記得最後還要使用'free'! –

+0

謝謝你的回答,但我不認爲這是真正的原因。我打印這些數據,它來自buf_right/buf_left/buf_disparity。 –

0

我覺得爲什麼會這樣。 在我的服務器代碼,有這樣的事情

if(send_flag) 
{ 
    send_left_image(); 
    send_right_image(); 
} 

但有時,當客戶端退出意外,我會重置send_left_image服務器()/ send_right_image()並等待連接。所以當客戶端重新連接時,send_right_image()仍然會被調用,然後在發生任何事情之前將一些數據發送給客戶端。

相關問題