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

时间:2016-11-15 03:05:55

标签: c++ multithreading sockets

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

原始代码: 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);
}

原始输出:
在阅读之前 读完后

新产出:
在阅读之前

1 个答案:

答案 0 :(得分: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));

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