当重新连接到服务器时,C套接字客户端接收大量数据

问题描述:

我在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

添加示例代码 –

据我了解,你在做这样的事情在你的服务器代码:

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。 –

我觉得为什么会这样。 在我的服务器代码,有这样的事情

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

但有时,当客户端退出意外,我会重置send_left_image服务器()/ send_right_image()并等待连接。所以当客户端重新连接时,send_right_image()仍然会被调用,然后在发生任何事情之前将一些数据发送给客户端。