当前位置: 技术问答>linux和unix
Linux下Socket得多线程问题,比较特殊,高手请进!
来源: 互联网 发布时间:2015-12-21
本文导语: 主程序中需要使用Socket通讯,同时还要干其他工作。所以对Socket通讯开一个线程,同时其他工作开一个线程。但是Socket要同时处理多个客户端的连接要求,所以Socket也要开多个线程。简单的说,就是Socket这个线程内部...
主程序中需要使用Socket通讯,同时还要干其他工作。所以对Socket通讯开一个线程,同时其他工作开一个线程。但是Socket要同时处理多个客户端的连接要求,所以Socket也要开多个线程。简单的说,就是Socket这个线程内部,又开了多个线程,请问这种实现方式能行么?谢谢!
高手能否给个例子或者给写个大体的程序框架,谢谢,马上送分!
高手能否给个例子或者给写个大体的程序框架,谢谢,马上送分!
|
void thread(void)
{
int i;
printf("This is a pthread.n");
ret=pthread_create(&id,NULL,(void *) socket_pro,NULL);
}
int main(void)
{
pthread_t id;
int i,ret;
ret=pthread_create(&id,NULL,(void *) thread,NULL);
if(ret!=0){
printf ("Create pthread error!n");
exit (1);
}
printf("This is the main process");
pthread_join(id,NULL);
return (0);
}
void socket_pro(void)
{
int i;
printf("This is socket_pro");
SOCKET socketfd;
socketfd=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
//bind a socket
............................
if(bind(socketfd,(SOCKADDR*)&service,sizeof(service))==SOCKET_ERROR)
........................................
//listen on a socket
if(listen(socketfd,20)==SOCKET_ERROR)
printf("Error .n");
else
printf("listening ok.n");
//accept a connection
while(1)
{
..................................
accept............
printf("Client Connected.n");
{
CreateThread
}
}
}
大概是这样,另外所有线程之间要互斥的,尤其是你做其他工作和socket client 之间。
http://man.lupaworld.com/content/develop/joyfire/system/11.html#I260 可以去看看
{
int i;
printf("This is a pthread.n");
ret=pthread_create(&id,NULL,(void *) socket_pro,NULL);
}
int main(void)
{
pthread_t id;
int i,ret;
ret=pthread_create(&id,NULL,(void *) thread,NULL);
if(ret!=0){
printf ("Create pthread error!n");
exit (1);
}
printf("This is the main process");
pthread_join(id,NULL);
return (0);
}
void socket_pro(void)
{
int i;
printf("This is socket_pro");
SOCKET socketfd;
socketfd=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
//bind a socket
............................
if(bind(socketfd,(SOCKADDR*)&service,sizeof(service))==SOCKET_ERROR)
........................................
//listen on a socket
if(listen(socketfd,20)==SOCKET_ERROR)
printf("Error .n");
else
printf("listening ok.n");
//accept a connection
while(1)
{
..................................
accept............
printf("Client Connected.n");
{
CreateThread
}
}
}
大概是这样,另外所有线程之间要互斥的,尤其是你做其他工作和socket client 之间。
http://man.lupaworld.com/content/develop/joyfire/system/11.html#I260 可以去看看
|
楼主说:Socket要同时处理多个客户端的连接要求,所以Socket也要开多个线程.
我觉得服务端socket一直处于监听状态.在有客户端连接以后(及服务器端accept之后)
pthread_create比较好!
我觉得服务端socket一直处于监听状态.在有客户端连接以后(及服务器端accept之后)
pthread_create比较好!
|
你参考一下: 这是用进程去处理链入得客户端业务得:
一个循环TCP服务源代码(因为用fork进行多进程服务了,所以这种服务现实中也有用)如下:
[CODE]
/*----------------------源代码开始--------------------------------------------*/
#include
#include
#include
#include
#include
#include
#include
#include
/*********************************************************************
*filename: cycletcpserver.c
*purpose: 循环tcp服务端程序
*tidied by: zhoulifa(zhoulifa@163.com) 周立发(http://zhoulifa.bokee.com)
Linux爱好者 Linux知识传播者 SOHO族 开发者 最擅长C语言
*date time:2006-07-04 22:00:00
*Note: 任何人可以任意复制代码并运用这些文档,当然包括你的商业用途
* 但请遵循GPL
*Thanks to: Google.com
*********************************************************************/
int main(int argc, char ** argv)
{
int sockfd,new_fd; /* 监听socket: sock_fd,数据传输socket: new_fd */
struct sockaddr_in my_addr; /* 本机地址信息 */
struct sockaddr_in their_addr; /* 客户地址信息 */
unsigned int sin_size, myport, lisnum;
if(argv[1]) myport = atoi(argv[1]);
else myport = 7838;
if(argv[2]) lisnum = atoi(argv[2]);
else lisnum = 2;
if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(1);
}
my_addr.sin_family=PF_INET;
my_addr.sin_port=htons(myport);
my_addr.sin_addr.s_addr = INADDR_ANY;
bzero(&(my_addr.sin_zero), 0);
if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) {
perror("bind");
exit(1);
}
if (listen(sockfd, lisnum) == -1) {
perror("listen");
exit(1);
}
while(1) {
sin_size = sizeof(struct sockaddr_in);
if ((new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size)) == -1) {
perror("accept");
continue;
}
printf("server: got connection from %sn",inet_ntoa(their_addr.sin_addr));
if (!fork()) { /* 子进程代码段 */
if (send(new_fd, "Hello, world!n", 14, 0) == -1) {
perror("send");
close(new_fd);
exit(0);
}
}
close(new_fd); /*父进程不再需要该socket*/
waitpid(-1,NULL,WNOHANG);/*等待子进程结束,清除子进程所占用资源*/
}
}
一个循环TCP服务源代码(因为用fork进行多进程服务了,所以这种服务现实中也有用)如下:
[CODE]
/*----------------------源代码开始--------------------------------------------*/
#include
#include
#include
#include
#include
#include
#include
#include
/*********************************************************************
*filename: cycletcpserver.c
*purpose: 循环tcp服务端程序
*tidied by: zhoulifa(zhoulifa@163.com) 周立发(http://zhoulifa.bokee.com)
Linux爱好者 Linux知识传播者 SOHO族 开发者 最擅长C语言
*date time:2006-07-04 22:00:00
*Note: 任何人可以任意复制代码并运用这些文档,当然包括你的商业用途
* 但请遵循GPL
*Thanks to: Google.com
*********************************************************************/
int main(int argc, char ** argv)
{
int sockfd,new_fd; /* 监听socket: sock_fd,数据传输socket: new_fd */
struct sockaddr_in my_addr; /* 本机地址信息 */
struct sockaddr_in their_addr; /* 客户地址信息 */
unsigned int sin_size, myport, lisnum;
if(argv[1]) myport = atoi(argv[1]);
else myport = 7838;
if(argv[2]) lisnum = atoi(argv[2]);
else lisnum = 2;
if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(1);
}
my_addr.sin_family=PF_INET;
my_addr.sin_port=htons(myport);
my_addr.sin_addr.s_addr = INADDR_ANY;
bzero(&(my_addr.sin_zero), 0);
if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) {
perror("bind");
exit(1);
}
if (listen(sockfd, lisnum) == -1) {
perror("listen");
exit(1);
}
while(1) {
sin_size = sizeof(struct sockaddr_in);
if ((new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size)) == -1) {
perror("accept");
continue;
}
printf("server: got connection from %sn",inet_ntoa(their_addr.sin_addr));
if (!fork()) { /* 子进程代码段 */
if (send(new_fd, "Hello, world!n", 14, 0) == -1) {
perror("send");
close(new_fd);
exit(0);
}
}
close(new_fd); /*父进程不再需要该socket*/
waitpid(-1,NULL,WNOHANG);/*等待子进程结束,清除子进程所占用资源*/
}
}
|
送你个多线程处理的服务器端范例:
int main(int argc,char *argv[]) //需要一个参数 端口号
{
int listenfd, //监听套接字sock
connectfd; //accept 收到的 新套接字
struct sockaddr_in servAddr, //服务器地址
cliAddr; //客户端地址
socklen_t adrlen; //sockaddr地址长度
int servPort; //服务器监听端口号
pid_t pid; /*进程ID,多进程程序使用*/
/*struct packagehead *packhead;*/ //数据包头,下面是多线程所要所用到的变量
ARG *arg;
int rc;
pthread_t id;
//获得服务器监听的端口号
if(argc!=2)
{
printf("Usage:%s portnumberan",argv[0]);
return 1;
}
if((servPort=atoi(argv[1]))client);
delete arg;
pthread_exit(NULL);
}
int main(int argc,char *argv[]) //需要一个参数 端口号
{
int listenfd, //监听套接字sock
connectfd; //accept 收到的 新套接字
struct sockaddr_in servAddr, //服务器地址
cliAddr; //客户端地址
socklen_t adrlen; //sockaddr地址长度
int servPort; //服务器监听端口号
pid_t pid; /*进程ID,多进程程序使用*/
/*struct packagehead *packhead;*/ //数据包头,下面是多线程所要所用到的变量
ARG *arg;
int rc;
pthread_t id;
//获得服务器监听的端口号
if(argc!=2)
{
printf("Usage:%s portnumberan",argv[0]);
return 1;
}
if((servPort=atoi(argv[1]))client);
delete arg;
pthread_exit(NULL);
}