当前位置: 技术问答>linux和unix
多线程socket服务器端的问题!急!
来源: 互联网 发布时间:2016-04-18
本文导语: 要实现手机和pc之间的通信,可以同时多个手机客户端进行连接通信,但是现在碰到一个问题,第一个客户端连接上后,再用第2个手机进行连接,第1个手机就会超时关闭,这样根本就没有实现多线程功能,请教大家看看代码,帮...
要实现手机和pc之间的通信,可以同时多个手机客户端进行连接通信,但是现在碰到一个问题,第一个客户端连接上后,再用第2个手机进行连接,第1个手机就会超时关闭,这样根本就没有实现多线程功能,请教大家看看代码,帮我解决下这个问题,最好能帮我修改下,谢谢!
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define REQUEST_NUM 10
#define MAX_CONNECTED_NUM 10
#define MAX_DATE_SIZE 1024
void *server_thread (void *fd)
{
char revbuf[MAX_DATE_SIZE];
char sendbuf[MAX_DATE_SIZE];
struct sockaddr_rc addr_client;
int len_addr=sizeof(addr_client);
int sockfd = (int) fd;
int error;
int sendbytes;
if ((error = pthread_detach (pthread_self ())) != 0)
{
close (sockfd);
perror ("Can't detach server thread.");
pthread_exit ((void*)1);
}
printf("the server thread ID is:%lun",pthread_self());
getsockname(sockfd, (struct sockaddr *)&addr_client, &len_addr);
while(1)
{
memset (revbuf, 0, sizeof(revbuf));
if ((error = recv (sockfd, revbuf, sizeof(revbuf), MSG_NOSIGNAL)) 0)
{
if(FD_ISSET(listenfd,&readfd)>0)
{
if ((connectfd =accept (listenfd, (struct sockaddr *) &addr_client, &len_addr)) == -1)
{
perror ("connect error:");
printf("exit!n");
exit(1);
}
memset(temp,0,sizeof(temp));
ba2str(&addr_client.rc_bdaddr,temp);
printf("accept conenction from: %sn",temp);
pthread_create (&tid, NULL, server_thread, (void *) connectfd);
}
}
}
close (listenfd);
fprintf (stderr, "just a test,wish success!n");
return 0;
}
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define REQUEST_NUM 10
#define MAX_CONNECTED_NUM 10
#define MAX_DATE_SIZE 1024
void *server_thread (void *fd)
{
char revbuf[MAX_DATE_SIZE];
char sendbuf[MAX_DATE_SIZE];
struct sockaddr_rc addr_client;
int len_addr=sizeof(addr_client);
int sockfd = (int) fd;
int error;
int sendbytes;
if ((error = pthread_detach (pthread_self ())) != 0)
{
close (sockfd);
perror ("Can't detach server thread.");
pthread_exit ((void*)1);
}
printf("the server thread ID is:%lun",pthread_self());
getsockname(sockfd, (struct sockaddr *)&addr_client, &len_addr);
while(1)
{
memset (revbuf, 0, sizeof(revbuf));
if ((error = recv (sockfd, revbuf, sizeof(revbuf), MSG_NOSIGNAL)) 0)
{
if(FD_ISSET(listenfd,&readfd)>0)
{
if ((connectfd =accept (listenfd, (struct sockaddr *) &addr_client, &len_addr)) == -1)
{
perror ("connect error:");
printf("exit!n");
exit(1);
}
memset(temp,0,sizeof(temp));
ba2str(&addr_client.rc_bdaddr,temp);
printf("accept conenction from: %sn",temp);
pthread_create (&tid, NULL, server_thread, (void *) connectfd);
}
}
}
close (listenfd);
fprintf (stderr, "just a test,wish success!n");
return 0;
}
|
int sockfd = (int) fd;
你的程序可以工作? 这一句都不对吧。笔误?
|
你的程序可能可以工作,但是这样写是非常不好的,给pthread_create()传入的数据参数是指针类型!建议修改如下几处看看:
1. pthread_create (&tid, NULL, server_thread, (void *) &connectfd);
2. int sockfd = *(int*)fd;
good luck!
1. pthread_create (&tid, NULL, server_thread, (void *) &connectfd);
2. int sockfd = *(int*)fd;
good luck!
|
当recv 的结果==0的时候,是手机端主动发出连接,线程里要调用close,当recv == -1的时候,检查一下系统的errno,如果errno==EINTR,继续执行recv,errno!=EINTR的时候,线程主动close掉..
当recv==-1,且errno==EINTR的时候,由信号中断引起返回,并非客户端断开连接了,要区别对待,继续执行recv
当recv==-1,且errno==EINTR的时候,由信号中断引起返回,并非客户端断开连接了,要区别对待,继续执行recv
|
如guosha 所言!但是有一点更正下:
select最后一个timeout参数: (struct timeval *)0 应该是表示NULL,也就是所select在不可用用的时候是block的,而不是空循环。
只有当timevale->tv_sec = 0; timevale->tv_usec=0的时候,select才会立马返回,类似polling
good luck!
|
只有 一个 套接字 需要读,没必要用select
|
最主要的问题是 同一进程中的线程是共享内存对象的,你的客户端地址对象只定义了一个,下一个连接来的时候就被后一个客户端连接冲掉了
应该如下定义
struct sockaddr_rc addr_server, *addr_client;
在select 成功后new 一个sockaddr_rc对象出来并将addr_client指向该对象,然后再使用
应该如下定义
struct sockaddr_rc addr_server, *addr_client;
在select 成功后new 一个sockaddr_rc对象出来并将addr_client指向该对象,然后再使用
|
shutdown(listenfd);
|
LZ先把有明显错误的地方改了。楼上也有提到的pthread_create (&tid, NULL, server_thread, (void *)&connectfd)
所有的服务子线程都引用了同一个栈变量connectfd,后一个连接总会覆盖前一个,新的连接connectfd都在堆上分配是一种替代方案。
所有的服务子线程都引用了同一个栈变量connectfd,后一个连接总会覆盖前一个,新的连接connectfd都在堆上分配是一种替代方案。
|
没作过蓝牙程序,提供不了什么信息
不过上面提的有关的(void *)connectfd 的问题,开始你的用法是正确,只是让人看得别扭而已
另外作为一个服务程序,我不太赞同一个连接一个线程的方式,虽然没有错,但是在一个真正的产品中不应该出现这种做法--个人意见。
对于recv函数,返回0表示对端断开连接,而返回
不过上面提的有关的(void *)connectfd 的问题,开始你的用法是正确,只是让人看得别扭而已
另外作为一个服务程序,我不太赞同一个连接一个线程的方式,虽然没有错,但是在一个真正的产品中不应该出现这种做法--个人意见。
对于recv函数,返回0表示对端断开连接,而返回