【问题标题】:C++ multithread socket cannot receive client dataC ++多线程套接字无法接收客户端数据
【发布时间】: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 的大小。谢谢提醒。

标签: c++ multithreading sockets


【解决方案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() 传递。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-08-27
    • 1970-01-01
    • 2016-08-27
    • 2018-03-26
    • 2013-03-19
    • 2021-01-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多