• 全部
...

linux C TCP UDP server 接收多个客户端同时连接的多线程

weixin_30072103 2018-07-13 10:00:38
我想做一个的TCP UDP server端,实现这样一个功能:每当一个客户端连接过来时,创建一个单独的线程去处理这个客户端。
现在测试发现,当多个TCP客户端连接进来的时候,只会保留最新的一个客户端线程通信,先连接进来的客户端线程都没在运行也无法发送数据?怎么回事?本人小白,请多指教。以下是代码:

#include ..一些头文件,省略。
#define LOCAL_IP "192.168.1.66"
#define LOCAL_PORT 8888
struct pthread_arg//供线程使用的参数
{
char protocol;// protocol =='U'为udp连接 ; protocol == 'T'则为tcp连接;
int fd;
struct sockaddr_in sock;
int num;
};

static void *deal_send_pth(void *arg)
{
struct pthread_arg *r=( struct pthread_arg *)arg;
printf("pth%d running...\n",r->num);

}

main()
{
int i;
struct sockaddr_in server_addr, client_addr;
struct pthread_arg ptr_arg;//供线程使用的参数
fd_set fdset;
pthread_t pthid;
int tcp_socketfd, tcp_connectfd, udp_connectfd, maxfd;
int client_len;
char local_port[32], local_ip[32];
int reuse = 1;//进程结束后端口允许重用,否则在调试程序时得等系统回收端口,浪费时间
void *retval;

//--------------------- TCP ----------------------------------------------------------
if((tcp_socketfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
printf("fail to socket!!\n");
exit(-1);
}
printf("socket success!!\n");
setsockopt(tcp_socketfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(int));

bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;

sprintf(local_ip, "%s", LOCAL_IP);
server_addr.sin_addr.s_addr = inet_addr(local_ip);
printf("[server ip = %s]\n", local_ip);
sprintf(local_port, "%d", LOCAL_PORT);
server_addr.sin_port = htons(atoi(local_port));
printf("[tcp server port = %s]\n", local_port);

if(bind(tcp_socketfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
{
perror("fail to bind!!");
exit(-1);
}

if(listen(tcp_socketfd, 5) < 0)
{
perror("fail to listen!!");
exit(-1);
}


//--------------------- UDP ---------------------------------------------------------------------
server_addr.sin_port = htons(atoi(local_port));
printf("[udp server port = %s]\n", local_port);

if((udp_connectfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
perror("Error : udp fail to socket!!\n");
exit(-1);
}

if(bind(udp_connectfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
{
perror("Error : udp fail to bind!!\n");
exit(-1);
}

maxfd = (tcp_connectfd > udp_connectfd ? tcp_connectfd : udp_connectfd);

while(1)
{
struct sockaddr_in client_addr;
FD_ZERO(&fdset);
FD_SET(tcp_socketfd, &fdset);
FD_SET(udp_connectfd, &fdset);
if(select(maxfd+1, &fdset, NULL, NULL, NULL)< 0)
{
perror("Error: select error!!\n");
exit(-1);
}
//tcp连接-------------------------------
//为每一个tcp客户端创建独立的处理线程,线程处理函数为deal_send_pth,参数为ptr_arg
if(FD_ISSET(tcp_socketfd, &fdset))
{
printf("----------pass 2 -------------\n");
sleep(1);
//循环接受客户端的链接请求
client_len = sizeof(client_addr);
if((tcp_connectfd = accept(tcp_socketfd, (struct sockaddr *)&client_addr, (socklen_t *)&(client_len))) < 0)
{
perror("fail to accept!!");
return -1;
}
ptr_arg.protocol = 'T';
ptr_arg.fd = tcp_connectfd;
memcpy((char *)&ptr_arg.sock, (const char *)&client_addr,sizeof(struct sockaddr_in));
ptr_arg.num = i;
if(pthread_create(&pthid, NULL, deal_send_pth, (void *)&ptr_arg) < 0)
{
perror("fail to pthread_create!!");
return -1;
}
pthread_detach(pthid);//回收线程、非阻塞
i++;
}
}
}
...全文
给本帖投票
1111 4 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
同IP同port两个程序同时接收可以实现么?
weixin_30072103 2018-07-16
  • 打赏
  • 举报
回复
引用 2 楼 sghcpt 的回复:
楼主:应该是下面的代码由问题吧?
ptr_arg.protocol = 'T';
ptr_arg.fd = tcp_connectfd;
memcpy((char *)&ptr_arg.sock, (const char *)&client_addr,sizeof(struct sockaddr_in));
ptr_arg.num = i;
if(pthread_create(&pthid, NULL, deal_send_pth, (void *)&ptr_arg) < 0)

其中ptr_arg变量,每次接受到一个新客户端连接时,就把这个这个变量值赋值为最新的,而之前保存的那些字应该给覆盖了。所以最后只有一个fd有效了,因为你把以指针参数的方式传给线程使用。楼主可以动态分配ptr_arg值,每次新客户端连接进来就动态分配一个,再传个线程,这样就应该可以了。


不是这个问题,现在问题已经解决了,非常感谢。
赵4老师 2018-07-13
  • 打赏
  • 举报
回复
参考epoll源代码相关片断。
sghcpt 2018-07-13
  • 打赏
  • 举报
回复
楼主:应该是下面的代码由问题吧?
ptr_arg.protocol = 'T';
ptr_arg.fd = tcp_connectfd;
memcpy((char *)&ptr_arg.sock, (const char *)&client_addr,sizeof(struct sockaddr_in));
ptr_arg.num = i;
if(pthread_create(&pthid, NULL, deal_send_pth, (void *)&ptr_arg) < 0)

其中ptr_arg变量,每次接受到一个新客户端连接时,就把这个这个变量值赋值为最新的,而之前保存的那些字应该给覆盖了。所以最后只有一个fd有效了,因为你把以指针参数的方式传给线程使用。楼主可以动态分配ptr_arg值,每次新客户端连接进来就动态分配一个,再传个线程,这样就应该可以了。

70,017

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧

手机看
关注公众号

关注公众号

客服 返回
顶部