C ++多线程套接字无法接收客户端数据

Posted

技术标签:

【中文标题】C ++多线程套接字无法接收客户端数据【英文标题】:C++ multithread socket cannot receive client data 【发布时间】:2016-11-15 03:05:54 【问题描述】:

我想创建一个多线程套接字服务器。我的服务器工作正常,但是当我尝试将我的代码移动到工作函数中时,服务器在读取客户端数据时停止工作。

原代码: main.cpp

int sock;

main()
    SocketServer *ss = new SocketServer(8888);
    pthread_t thread;
    if(ss != NULL)
        while(true)            
            sock = ss->Accept();   
            char* out;
            ss->GetRequest(sock, out);  
        
    

SocketServer.cpp

void SocketServer::GetRequest(int msgsock, char* out)
    char buf[1024];
    int rval;
    std::cout<<"before read\n";
    if ((rval = read(msgsock, buf, 1024)) < 0)
        perror("reading socket");
    else
        strcpy(out,buf);
    
    std::cout<<"after read\n";   

添加线程后: main.cpp

int sock;

main()
    SocketServer *ss = new SocketServer(8888);
    pthread_t thread;
    if(ss != NULL)
        while(true)            
            sock = ss->Accept();      
            pthread_create(&thread, NULL, SocketThread, &(*ss));       
            pthread_detach(thread);     
        
    


static void* SocketThread(void* lp)    
    SocketServer *ss = (SocketServer*) lp;
    char* out;
    ss->GetRequest(sock, out);

原始输出: 阅读前 看完后

新输出: 阅读前

【问题讨论】:

这完全坏了。如果同时收到两个连接,您认为会发生什么?只有一个sock 全局变量。你认为out 指向哪里,GetRequest 会写信到哪里?您需要学习如何使用调试器。 @SamVarshavchik 我只包含了与错误相关的代码的 sn-ps。 out 和 GetRequest 正在写回 main。如果需要,我可以上传其他代码。 如果你不知道你的错误在哪里,那么你就不知道这些“sn-ps”是否相关。 C++ 没那么简单。仅仅因为程序在某个特定位置崩溃或无法运行并不意味着这就是错误所在。根据显示的代码唯一可以确定的是显示的代码中存在多个基本错误。 @SamVarshavchik 我发现了问题所在。看来我需要指定 out 的大小。谢谢提醒。 【参考方案1】:

这个坏了:

if ((rval = read(msgsock, buf, 1024)) < 0)
    perror("reading socket");
else
    strcpy(out,buf);

您将忽略rval,除非它发出错误信号。应该是:

if ((rval = read(msgsock, buf, 1024)) < 0)
    perror("reading socket");
else if (rval == 0) 
    // peer closed the connection
    close(msgsock); // or closesocket(), depending on your platform
    break;
else
    strncpy(out,buf,rval);

这也坏了:

sock = ss->Accept();      
pthread_create(&thread, NULL, SocketThread, &(*ss));

开始处理客户端的线程对监听套接字没有兴趣。它需要的是 accepted 套接字sock,并且它需要以不会在下一次调用时被覆盖的方式获取它。通常sock 是接受循环中的局部变量,并通过pthread_create() 传递。

【讨论】:

以上是关于C ++多线程套接字无法接收客户端数据的主要内容,如果未能解决你的问题,请参考以下文章

C# 多线程 大量数据实时接收\解析\存储 问题

非阻塞套接字多线程接收模型

没有多线程的 C++ 套接字非同步/并行代码

在 C 中使用多线程服务器时无法完成文件传输

多线程 Udp 服务器:将接收到的数据重定向到线程

带有进度条更新的 C++ 多线程套接字操作