我想创建一个多线程套接字服务器。我让服务器工作正常,但当我尝试将我的代码移动到工作函数时,服务器在读取客户端数据时停止工作。
原始代码: 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);
}
原始输出:
在阅读之前
读完后
新产出:
在阅读之前
答案 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()
传递。