Linux C语言 socket 多线程(循环创建多个线程,同时进行,非阻塞)
我看了一些博客,多线程网络编程用的是堵塞,也就是 pthread_join函数,可是既然是监听接口怎么能用堵塞的。我要做的东西是:监听80端口,然后接收请求,创建一个线程完成相应任务。我遇到的问题是:用阻塞(也就是pthread_join(thread_id))相当于单线程无法满足要求,用非阻塞(pthread_detach(thread_id))然后我的socket没反应。问题原因...
·
我看了一些博客,多线程网络编程用的是堵塞,也就是 pthread_join 函数,可是既然是监听接口怎么能用堵塞的。
我要做的东西是:监听80端口,然后接收请求,创建一个线程完成相应任务。
我遇到的问题是:用阻塞(也就是pthread_join(thread_id))相当于单线程无法满足要求,用非阻塞(pthread_detach(thread_id))然后我的socket没反应。
问题原因:在一个循环中创建的Socket,如果socket的id是局部变量那么当前循环结束后,该变量的空间就会被回收掉,导致进入线程函数之后,获取不到socket的id的值。
解决方法:用malloc申请一个int的空间存储socket的id,然后在线程中释放这片空间。
接下来放错误代码和成功代码:
错误代码1:(不算错误,只是用了阻塞,创建的线程未执行完之前不会创建其他线程)
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <string.h>
#include <ctype.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <errno.h>
#include <time.h>
#include <pthread.h>
#define SERVER_PORT 80
void aligenie_thread(void *tSock);
int main(void)
{
int sock;
struct sockaddr_in server_addr;
sock = socket(AF_INET,SOCK_STREAM,0);
bzero(&server_addr,sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(SERVER_PORT);
bind(sock,(struct sockaddr *)&server_addr,sizeof(server_addr));
listen(sock,128);//监听
printf("waiting for t's connect\n");
int i = 0;
while(1)
{
struct sockaddr_in tmall;
int tSock = 0;//注意三个程序中这里的区别
int tmall_addr_len = sizeof(tmall);
tmall_addr_len = sizeof(tmall);
tSock = accept(sock,(struct sockaddr *)&tmall,&tmall_addr_len);//接收到请求
if(tSock<0)
{
close(tSock);
continue;
}
pthread_t id;
int ret;
ret = pthread_create(&id,NULL,(void *)aligenie_thread,(void *)&tSock);//创建线程
if(ret != 0)
{
printf(" Creat pthread error!\n");
}
printf("\nthread %d !\n",i++);
pthread_join(id,NULL);//线程是阻塞的
}
return 0;
}
void aligenie_thread(void *tSock)
{
int tmSock =*((int*)tSock);//获取socket的id
write(tmSock,"hello world",strlen("hello world"));
close(tmSock);
pthread_exit(NULL);
}
错误代码2:(虽然是非阻塞的,但是socket的id进入线程后空间马上就被回收了)
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <string.h>
#include <ctype.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <errno.h>
#include <time.h>
#include <pthread.h>
#define SERVER_PORT 80
void aligenie_thread(void *tSock);
int main(void)
{
int sock;
struct sockaddr_in server_addr;
sock = socket(AF_INET,SOCK_STREAM,0);
bzero(&server_addr,sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(SERVER_PORT);
bind(sock,(struct sockaddr *)&server_addr,sizeof(server_addr));
listen(sock,128);//监听
printf("waiting for t's connect\n");
int i = 0;
while(1)
{
struct sockaddr_in tmall;
int tSock = 0;//注意三个程序中这里的区别
int tmall_addr_len = sizeof(tmall);
tmall_addr_len = sizeof(tmall);
tSock = accept(sock,(struct sockaddr *)&tmall,&tmall_addr_len);//接收到请求
if(tSock<0)
{
close(tSock);
continue;
}
pthread_t id;
int ret;
ret = pthread_create(&id,NULL,(void *)aligenie_thread,(void *)&tSock);//创建线程
pthread_detach(id);//线程非阻塞
if(ret != 0)
{
printf(" Creat pthread error!\n");
}
printf("\nthread %d !\n",i++);
}
return 0;
}
void aligenie_thread(void *tSock)
{
int tmSock =*((int*)tSock);//获取socket的id
write(tmSock,"hello world",strlen("hello world"));
close(tmSock);
pthread_exit(NULL);
}
正确的多线程:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <string.h>
#include <ctype.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <errno.h>
#include <time.h>
#include <pthread.h>
#define SERVER_PORT 80
void aligenie_thread(void *tSock);
int main(void)
{
int sock;
struct sockaddr_in server_addr;
sock = socket(AF_INET,SOCK_STREAM,0);
bzero(&server_addr,sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(SERVER_PORT);
bind(sock,(struct sockaddr *)&server_addr,sizeof(server_addr));
listen(sock,128);//监听
printf("waiting for t's connect\n");
int i = 0;
while(1)
{
struct sockaddr_in tmall;
int* tSock = (int *)malloc(sizeof(int));//注意三个程序中这里的区别
int tmall_addr_len = sizeof(tmall);
tmall_addr_len = sizeof(tmall);
*tSock = accept(sock,(struct sockaddr *)&tmall,&tmall_addr_len);//接收到请求
if(*tSock<0)
{
close(*tSock);
continue;
}
pthread_t id;
int ret;
ret = pthread_create(&id,NULL,(void *)aligenie_thread,(void *)tSock);//创建线程
pthread_detach(id);//线程非阻塞
if(ret != 0)
{
printf(" Creat pthread error!\n");
}
printf("\nthread %d !\n",i++);
}
return 0;
}
void aligenie_thread(void *tSock)
{
int tmSock =*((int*)tSock);//获取socket的id
free(tSock);//在这里释放空间
write(tmSock,"hello world",strlen("hello world"));
close(tmSock);
pthread_exit(NULL);
}
记录:记得给socket的id分配空间,用完之后记得free掉
更多推荐
已为社区贡献1条内容
所有评论(0)