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

标签 c sockets tcp client

我在 C 套接字中运行时出现问题。 有一个服务器,有一个客户端。服务器向客户端发送大量数据。当我按CTRL+C终止客户端时,我重新启动服务器(1、关闭套接字fd,2、再次构建套接字fd)。 但是当我再次运行客户端时,它从上次连接中接收到大量数据。我猜数据在服务器发送缓冲区中。当我上次关闭客户端时,那里仍然有数据。 有什么办法可以清除数据吗? 谢谢

示例代码

    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;
}

最佳答案

据我了解,您在服务器代码中做了类似的事情:

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);

如果是这种情况,您应该在执行 read() 之前清除缓冲区消息

一个简单的方法是使用 memset() ,所以这部分代码将如下所示:

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

关于C套接字客户端重新连接到服务器时收到大量数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46048586/

相关文章:

c - 按位运算和填充字节在一起

c - 发送UDP包到NTP服务器并接收时间(lwip、Cortex M3、Stellaris LM3S6965评估板)

c# - 轮询数千个 TCP 套接字

c - 错误 : expected specifier-qualifier-list before

并发发送数据包

c - OpenCL 内核中存在问题的 while 循环 : Execution hangs

ruby - Ruby 中 TCP Socket.send 的第二个参数是什么?

objective-c - 在不将整个文件加载到 ram 的情况下,通过 HTTP POST 发送大文件的正确方法是什么?

tcp - 大量的 TIME_WAIT 会导致服务器瘫痪吗?

c++ - Qt套接字写段错误