linux下c++ socket 多线程问题

rwjlqn 2009-05-05 11:39:00
我写了一个socket的程序,客户端(也是linux平台)telnet ip地址 端口 后就能连上服务端
一开始我用fork实现客户端的并发问题
由于fork耗资源挺多的 就想把多进程改用多线程
结果改用多线程后遇到点问题 希望得到帮助:
当第一个用户连接后(现在还没退出) 第二个用户也连接上 然后第二个用户回车退出 结果第一个用户就不能正常退出 原因是client_fd被第二次连接的客户端给覆盖了 所以造成了第一个用户不能正常退出 现在的问题就是如何让第一个用户一按回车后能正常退出程序
代码:
int main()
{
...
...
while(1)
{
socklen_t sin_size;
int client_fd;
if ((client_fd = accept(sockfd, (struct sockaddr *)&remote_addr,&sin_size)) == -1)
{
cout<<"accept出错"<<endl;
exit(1);
}
cout<<"received a connection from "<<inet_ntoa(remote_addr.sin_addr)<<endl;


pthread_t id;
pthread_attr_t id_attr;
pthread_attr_init(&id_attr);
pthread_attr_setdetachstate(&id_attr,PTHREAD_CREATE_DETACHED);
cout<<"id: "<<id<<endl;
if (pthread_create(&id , &id_attr , thread, (void*)&client_fd) < 0 )//第二个用户一连 就覆盖前一个client_fd 怎么办?
{
cout<<"pthread_create error"<<endl;
}
}
}

void *thread(void *data)
{

pthread_detach (pthread_self ( ));
int *client_fd = (int*)data;
cout<<"thread *client_fd: "<<*client_fd<<endl;
string receive = "";
int recvbytes;
char buf[1024];
recvbytes = recv(*client_fd ,buf ,sizeof(buf) ,0);

cout<<"*client_fd 1:"<<*client_fd<<endl;
buf[recvbytes] = '\0' ;
receive = receive + buf;
close(*client_fd);
if(receive != "")
{
SplitString(receive);
}
pthread_exit(NULL);
}
...全文
1187 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
rwjlqn 2009-05-06
  • 打赏
  • 举报
回复
现在有种想亲亲你的冲动啊 按你的想法(内部传参) 果然搞定了
谢谢你 老师
pope_key 2009-05-05
  • 打赏
  • 举报
回复
用c++最好就是用好类库
pope_key 2009-05-05
  • 打赏
  • 举报
回复
http://blog.csdn.net/CutBug/archive/2009/01/05/3715783.aspx
liqinghua1653 2009-05-05
  • 打赏
  • 举报
回复
你这里不能有同一个socket变量来保存多个连接。 建议一个线程用一个socket变量。
  • 打赏
  • 举报
回复
有点跑题了 在thread函数中 要按回车要关闭对应的client_fd 你如何判断你对应的client_fd呢?
我测试的结果是:每次都关闭最后一个client_fd 前面的都覆盖了

那是你代码有问题,不知道你后来怎么测的。我只提供一种思路。

你这种问题unix网络编程-实用技术与实例分析的第6章。6.3.4节已经讲了3种情况。

我提供给你的表,是类似第3种,外部分配空间,并传递参数,不会有问题,出问题,可能是哪里没有维护好,我只能帮你提供思路,且可以保证这个思路是一定可行的。

你要觉得这样不行,我再提供你第2种方法

void *thread(void *data)
{

pthread_detach (pthread_self ( ));
int *client_fd = (int*)data;
int c_fd=*client_fd ; //内部传参数,这样就可以了,后面的你自己改
cout < <"thread *client_fd: " < <*client_fd < <endl;
string receive = "";
int recvbytes;
char buf[1024];
recvbytes = recv(*client_fd ,buf ,sizeof(buf) ,0);

cout < <"*client_fd 1:" < <*client_fd < <endl;
buf[recvbytes] = '\0' ;
receive = receive + buf;
close(*client_fd);
if(receive != "")
{
SplitString(receive);
}
pthread_exit(NULL);
}

一个不是很复杂的问题,你可以自己思考的啊。
如果还出问题,肯定不是我这块思路的问题,你仔细排查代码吧。

或者拿书来看看也可以。
rwjlqn 2009-05-05
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 hairetz 的回复:]
int thread_num ; //记录线程数目
int client_fd;
int c_fd[MAX_CLIENT]; //主线程维护一个子线程连接描述符集合
...

c_fd[thread_num++]=client_fd;
if (pthread_create(&id , &id_attr , thread, (void*)&c_fd[thread_num-1]) < 0 )//第二个用户一连 就覆盖前一个client_fd 怎么办?
{
cout < <"pthread_create error" < <endl;
}
[/Quote]

有点跑题了 在thread函数中 要按回车要关闭对应的client_fd 你如何判断你对应的client_fd呢?
我测试的结果是:每次都关闭最后一个client_fd 前面的都覆盖了
  • 打赏
  • 举报
回复
int thread_num ; //记录线程数目
int client_fd;
int c_fd[MAX_CLIENT]; //主线程维护一个子线程连接描述符集合
...

c_fd[thread_num++]=client_fd;
if (pthread_create(&id , &id_attr , thread, (void*)&c_fd[thread_num-1]) < 0 )//第二个用户一连 就覆盖前一个client_fd 怎么办?
{
cout < <"pthread_create error" < <endl;
}



rwjlqn 2009-05-05
  • 打赏
  • 举报
回复
错误: 从‘void*’到‘int’的转换损失精
rwjlqn 2009-05-05
  • 打赏
  • 举报
回复
要是按你的做法的话 就会报错 而且容易出现段错误
rwjlqn 2009-05-05
  • 打赏
  • 举报
回复
if (pthread_create(&id , &id_attr , thread, (void)client_fd) < 0 )//

void *thread(void data)
{
pthread_detach (pthread_self ( ));
int client_fd
这样是不行的 该参数只能传递指针
  • 打赏
  • 举报
回复
if (pthread_create(&id , &id_attr , thread, (void)client_fd) < 0 )//


void *thread(void data)
{

pthread_detach (pthread_self ( ));
int client_fd = (int)data;
  • 打赏
  • 举报
回复
if (pthread_create(&id , &id_attr , thread, (void*)&client_fd) < 0 )//第二个用户一连 就覆盖前一个client_fd 怎么办?
{
cout < <"pthread_create error" < <endl;
}

服了你,还特地传个指针进去,你传个副本进去就可以了撒。

分离线程都会用,还不会处理这点小问题。



rwjlqn 2009-05-05
  • 打赏
  • 举报
回复
怎么弄啊????????
rwjlqn 2009-05-05
  • 打赏
  • 举报
回复
close(*client_fd);
关闭的总是最后一个连接服务端的client_fd 前面的client_fd早已被覆盖了
rwjlqn 2009-05-05
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 liliangbao 的回复:]
你用另一个变量保存client_fd如temp,并使用temp传给线程,并在线程中保存该变量~
[/Quote]

难道 temp = client_fd 后把temp传给线程 和用client_fd直接传给线程不一样吗??
liliangbao 2009-05-05
  • 打赏
  • 举报
回复
你用另一个变量保存client_fd如temp,并使用temp传给线程,并在线程中保存该变量~
rwjlqn 2009-05-05
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 pope_key 的回复:]
可以作为参数传过去撒
[/Quote]

大哥 你帮我修改一下吧 我弄了半天也不行
rwjlqn 2009-05-05
  • 打赏
  • 举报
回复
自己帮自己顶~~~~
pope_key 2009-05-05
  • 打赏
  • 举报
回复
可以作为参数传过去撒
rwjlqn 2009-05-05
  • 打赏
  • 举报
回复
在这里 一个线程如何使用一个socket变量啊 望指教

64,637

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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