linux下 socket多线程 socket泄露问题

likemm123 2016-08-10 02:07:24
大神们好。。。小弟最近做一个 项目 需要用到一对多 的服务端 socket开发。。。用于随时随地接受客户端发送过来的信息。。。用的socket协议。。。我选择了在linux上开发。。然后设计思路是多线程的 在进程的主线程里使用accept接受socket连接请求,然后为每个socket请求 创建一个线程,并发的为每一个客户端处理数据。。。但是发现客户端处理线程再跟客户端建立了socket连接之后虽然可以正常通信,但是经过一段较长时间后,客户端主动断开socket,服务端(read函数)没反应,这样就造成了,线程泄露,socket泄露,因为我的设定是,先判断客户端是否主动关闭了socket,才决定是否关闭线程。。。但是如果经过的时间较短的话,客户端主动断开,服务端(read函数)可以正常返回

我觉得虽然怀疑是read函数的问题 但是无法确定是什么原因 希望有大神帮我看看。。。以下附处理线程的代码:
void *thread_server(void *arg)
{
int Readres,Writeres;
bool IsConnection = true;
int sockfd;
sockfd = client_sockfd[(int)arg];
char buf[BUFNUM];
printf("enter subthread: %d -- %d\n",(int)arg,sockfd);
while(IsConnection)
{
memset(buf, '\0', sizeof(buf));
/*读取客户端发送的数据*/
Readres = read(sockfd, buf, sizeof(buf));
if(Readres == 0)
{
printf("read() return 0 ! this thread will exit! --from %d -- %d\n",(int)arg,sockfd);
IsConnection = false;
}
else if(Readres < 0)
{
printf("read() return ERROR:%d ==> %s! this thread will exit!\n",strerror(errno));
IsConnection = false;
}
else
{
printf("The Client say %d char: %s --from %d--%d\n",Readres,buf,(int)arg,sockfd);

/*处理客户端的数据*/
DataProcess(buf);

/*向客户端发送数据*/
//Writeres = write(sockfd, &(buf[BUFNUM]), sizeof(buf[BUFNUM]));
IsConnection = true;
}



}
close(sockfd);
pthread_exit(NULL);
}
...全文
1583 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
heronism 2018-02-08
  • 打赏
  • 举报
回复
用心跳是一种简单易行的方式
likemm123 2018-02-06
  • 打赏
  • 举报
回复
两年过去了。。。很抱歉没能及时感觉各位的回答。。。谢谢
  • 打赏
  • 举报
回复
服务器定时发送一个特定的cmd作为心跳包,如果一段时间没接收到这个命令,则表示断开连接了。
jasonM2008 2016-08-30
  • 打赏
  • 举报
回复
通过TCP的自带的心跳有可能会有问题,如果中间节点把你的TCP代理了一次,你的TCP心跳就没有用了。最好自己发送应用层的心跳包。
likemm123 2016-08-12
  • 打赏
  • 举报
回复
引用 4 楼 h2plus0 的回复:
要不使用setsockopt() 设置socket read timeout, 当返回 EAGAIN时,表示read timeout, 规定一段时间没读到数据,server就直接close(socket)... 从底层写socket,要想写一些高性能的服务器, 一般都比较复杂。。。
恩 我试试 非常感谢
likemm123 2016-08-12
  • 打赏
  • 举报
回复
引用 3 楼 u013682683 的回复:
[quote=引用 2 楼 h2plus0 的回复:] 可能是因为socket出现timeout状态,比如:一个tcp链接很长时间没有数据传送,路由器已经释放tcp链接, 客户端那边close了, 但服务器那边也不会有反应, 为了避免这种现象,可能需要改协议,比如:客户端每隔一段时间发送心跳数据包,如果长时间没有心跳,服务器关闭socket.
恩 谢谢 我在具体根据这个试试,话说 如果使用心跳包的方式判断的话 服务端这边 要怎么设置 或者说怎么写代码 用带什么调用?哎呀 ,刚开始写这方面的代码 完全没思路呀[/quote]恩 好的 我试试 非常感谢
h2plus0 2016-08-11
  • 打赏
  • 举报
回复
要不使用setsockopt() 设置socket read timeout, 当返回 EAGAIN时,表示read timeout, 规定一段时间没读到数据,server就直接close(socket)... 从底层写socket,要想写一些高性能的服务器, 一般都比较复杂。。。
likemm123 2016-08-11
  • 打赏
  • 举报
回复
引用 2 楼 h2plus0 的回复:
可能是因为socket出现timeout状态,比如:一个tcp链接很长时间没有数据传送,路由器已经释放tcp链接, 客户端那边close了, 但服务器那边也不会有反应, 为了避免这种现象,可能需要改协议,比如:客户端每隔一段时间发送心跳数据包,如果长时间没有心跳,服务器关闭socket.
恩 谢谢 我在具体根据这个试试,话说 如果使用心跳包的方式判断的话 服务端这边 要怎么设置 或者说怎么写代码 用带什么调用?哎呀 ,刚开始写这方面的代码 完全没思路呀
h2plus0 2016-08-10
  • 打赏
  • 举报
回复
可能是因为socket出现timeout状态,比如:一个tcp链接很长时间没有数据传送,路由器已经释放tcp链接, 客户端那边close了, 但服务器那边也不会有反应, 为了避免这种现象,可能需要改协议,比如:客户端每隔一段时间发送心跳数据包,如果长时间没有心跳,服务器关闭socket.
likemm123 2016-08-10
  • 打赏
  • 举报
回复
对了 我客户端是用的 SocketTool.exe 进行测试的。。。

23,110

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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