C++ socket多线程通讯,开启多线程Recv消息,第一个recv线程正常,第二个Recv线程开启后第一个就不能接收到消息

Co_priest 2015-09-11 01:40:10
//开启线程代码
int ServerSocket::OpenSocket()
{
//创建套接字
WORD myVersionRequest;
WSADATA wsaData;
myVersionRequest=MAKEWORD(1,1);
int err;
err=WSAStartup(myVersionRequest,&wsaData);
if (err)
{
return 1;
}

char *cp = LOCALHOST_IP;

JGlobal::s_sokcet = socket(AF_INET,SOCK_STREAM,0);//创建了可识别套接字
//需要绑定的参数
SOCKADDR_IN addr;
addr.sin_family=AF_INET;
//addr.sin_addr.S_un.S_addr=htonl(INADDR_ANY);//ip地址,自动获取
addr.sin_addr.S_un.S_addr=inet_addr(cp);
addr.sin_port=htons(6000);//绑定端口

int ret = bind(JGlobal::s_sokcet,(SOCKADDR*)&addr,sizeof(SOCKADDR));//绑定完成
ret = listen(JGlobal::s_sokcet,10);//其中第二个参数代表能够接收的最多的连接数 ,无错误返回0

if(!ret)
{
//HANDLE hThreadR = CreateThread(NULL,0,AccpetCilentProc,NULL,0,NULL);
CWinThread *pAcceptThread = AfxBeginThread(AccpetCilentProc,NULL,0,0,0);

//JGlobal::s_pGetNewstVIPThread = CreateThread(NULL,0,JNetUtils::GetNewestVIPThreadFunc,NULL,0,NULL);//开启获取VIP新消息线程
}
return 0;
}

UINT ServerSocket::AccpetCilentProc(LPVOID lpParam)
{
//开始进行监听
SOCKADDR_IN clientsocket;
int len=sizeof(SOCKADDR);
while (JGlobal::s_sokcet)
{
SOCKET serConn=accept(JGlobal::s_sokcet,(SOCKADDR*)&clientsocket,&len);//如果这里不是accept而是conection的话。。就会不断的监听
//ULONG cilentAddr = clientsocket.sin_addr.S_un.S_addr;
char *cp = inet_ntoa(clientsocket.sin_addr);
//MessageBox(GetDesktopWindow(),JUtils::ctowc(cp),_T("有客户上线了!"),0);
ULONG ip = inet_addr(cp);
Cinfo cilentInfo;
cilentInfo.serConn = serConn;
cilentInfo.MemIp = ip;
if(serConn > 0)
{
CWinThread *pAcceptThread = AfxBeginThread(RecvCilentProc,LPVOID(&cilentInfo),0,0,0);
}
}
return 0;
}


//recv线程入口函数
UINT ServerSocket::RecvCilentProc(LPVOID lpPrama)
{
int icount = 0;
while(JGlobal::s_sokcet > 0&&((Cinfo*)lpPrama)->serConn > 0)
{
icount++;

Cinfo t_cinfo = {0};
int rret = 0;
rret = recv(((Cinfo*)lpPrama)->serConn,(char *)&t_cinfo,sizeof(Cinfo),0);
//接收到的信息,已经有用户名、会员等级、价格需求结构体、客户状态、手机号码,
//需要补充IP、套接字接口、发送时间
if(rret > 0)
{
//消息处理
}
}
}





...全文
336 11 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
dooX8086 2015-09-12
  • 打赏
  • 举报
回复
// --------------------------------- Cinfo cilentInfo UINT ServerSocket::RecvCilentProc(LPVOID lpPrama) { SOCKET r_serConn = ((Cinfo*)lpPrama)->serConn; ULONG r_MemIp = ((Cinfo*)lpPrama)->MemIp; 这样做不是没坑,是坑大发了,线程是有优先级的. 不管是系统还是runtime 都没保证线程被create后立即执行 所以把一个局部变量的指针传给线程的做法是不可靠的
Co_priest 2015-09-11
  • 打赏
  • 举报
回复
引用 8 楼 mujiok2003 的回复:
[quote=引用 7 楼 Co_priest 的回复:] [quote=引用 5 楼 mujiok2003 的回复:] [quote=引用 4 楼 dooX8086 的回复:] cilentInfo; 需要 new 出来
正解。 [/quote]new应该也可以,不过内存负担会变大,我是在线程函数内部直接从参数获取到需要的值,不再去使用参数[/quote] 线程函数内拷贝的做法是不可靠的:如果拷贝还没有完成的时候已经被覆盖了呢?[/quote]说的也是,也要看情况,发一次帖子受益匪浅,感谢!
Co_priest 2015-09-11
  • 打赏
  • 举报
回复
引用 8 楼 mujiok2003 的回复:
[quote=引用 7 楼 Co_priest 的回复:] [quote=引用 5 楼 mujiok2003 的回复:] [quote=引用 4 楼 dooX8086 的回复:] cilentInfo; 需要 new 出来
正解。 [/quote]new应该也可以,不过内存负担会变大,我是在线程函数内部直接从参数获取到需要的值,不再去使用参数[/quote] 线程函数内拷贝的做法是不可靠的:如果拷贝还没有完成的时候已经被覆盖了呢?[/quote]UINT ServerSocket::RecvCilentProc(LPVOID lpPrama) { //取得参数的值 //获取IP SOCKET r_serConn = ((Cinfo*)lpPrama)->serConn; ULONG r_MemIp = ((Cinfo*)lpPrama)->MemIp; 我在这个函数进入时就直接取值了,应该没那么坑的可能吧
mujiok2003 2015-09-11
  • 打赏
  • 举报
回复
引用 7 楼 Co_priest 的回复:
[quote=引用 5 楼 mujiok2003 的回复:] [quote=引用 4 楼 dooX8086 的回复:] cilentInfo; 需要 new 出来
正解。 [/quote]new应该也可以,不过内存负担会变大,我是在线程函数内部直接从参数获取到需要的值,不再去使用参数[/quote] 线程函数内拷贝的做法是不可靠的:如果拷贝还没有完成的时候已经被覆盖了呢?
Co_priest 2015-09-11
  • 打赏
  • 举报
回复
引用 5 楼 mujiok2003 的回复:
[quote=引用 4 楼 dooX8086 的回复:] cilentInfo; 需要 new 出来
正解。 [/quote]new应该也可以,不过内存负担会变大,我是在线程函数内部直接从参数获取到需要的值,不再去使用参数
Co_priest 2015-09-11
  • 打赏
  • 举报
回复
引用 3 楼 lianshaohua 的回复:

Cinfo cilentInfo;
cilentInfo.serConn = serConn;
cilentInfo.MemIp = ip;
if(serConn > 0)
{
CWinThread *pAcceptThread = AfxBeginThread(RecvCilentProc,LPVOID(&cilentInfo),0,0,0);//线程中使用了局部对象的指针…………
}
}  
多谢!已经按前辈的思路解决好了
mujiok2003 2015-09-11
  • 打赏
  • 举报
回复
引用 4 楼 dooX8086 的回复:
cilentInfo; 需要 new 出来
正解。
dooX8086 2015-09-11
  • 打赏
  • 举报
回复
cilentInfo; 需要 new 出来
ztenv 版主 2015-09-11
  • 打赏
  • 举报
回复

Cinfo cilentInfo;
cilentInfo.serConn = serConn;
cilentInfo.MemIp = ip;
if(serConn > 0)
{
CWinThread *pAcceptThread = AfxBeginThread(RecvCilentProc,LPVOID(&cilentInfo),0,0,0);//线程中使用了局部对象的指针…………
}
}  
赵4老师 2015-09-11
  • 打赏
  • 举报
回复
参考成熟的socket多线程通讯开源项目的源代码片断。 比如epoll ?(其实我也没看过。
Co_priest 2015-09-11
  • 打赏
  • 举报
回复
C++ socket多线程通讯,开启多线程Recv消息,第一个recv线程正常,第二个Recv线程开启后第一个就不能接收到消息 ,这边是服务器的代码段,客户端程序测试可以发送OK,就是服务端没法接收到第一个线程的消息,不知道是线程被结束,还是因为线程创建第二个线程的参数会把第一个参数覆盖,内存的东西不怎么懂,求大神指点

65,186

社区成员

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

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