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)
{
//消息处理
}
}
}





...全文
308 11 打赏 收藏 转发到动态 举报
写回复
用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,就是服务端没法接收到第一个线程的消息,不知道是线程被结束,还是因为线程创建第二个线程的参数会把第一个参数覆盖,内存的东西不怎么懂,求大神指点
Linux网络编程(总共41集) 讲解Linux网络编程知识,分以下四个篇章。 Linux网络编程之TCP/IP基础篇 Linux网络编程之socket编程篇 Linux网络编程之进程间通信篇 Linux网络编程之线程篇 Linux网络编程之TCP/IP基础篇 01TCPIP基础(一) ISO/OSI参考模型 TCP/IP四层模型 基本概念(对等通信、封装、分用、端口) 02TCPIP基础(二) 最大传输单元(MTU)/路径MTU 以太网帧格式 ICMP ARP RARP 03TCPIP基础(三) IP数据报格式 网际校验和 路由 04TCPIP基础(四) TCP特点 TCP报文格式 连接建立三次握手 连接终止四次握手 TCP如何保证可靠性 05TCPIP基础(五) 滑动窗口协议 UDP特点 UDP报文格式 Linux网络编程之socket编程篇 06socket编程(一) 什么是socket IPv4套接口地址结构 网络字节序 字节序转换函数 地址转换函数 套接字类型 07socket编程(二) TCP客户/服务器模型 回射客户/服务器 socket、bind、listen、accept、connect 08socket编程(三) SO_REUSEADDR 处理多客户连接(process-per-conection) 点对点聊天程序实现 09socket编程(四) 流协议与粘包 粘包产生的原因 粘包处理方案 readn writen 回射客户/服务器 10socket编程(五) read、write与recv、send readline实现 用readline实现回射客户/服务器 getsockname、getpeername gethostname、gethostbyname、gethostbyaddr 11socket编程(六) TCP回射客户/服务器 TCP是个流协议 僵进程与SIGCHLD信号 12socket编程(七) TCP 11种状态 连接建立三次握手、连接终止四次握手 TIME_WAIT与SO_REUSEADDR SIGPIPE 13socket编程(八) 五种I/O模型 select 用select改进回射客户端程序 14socket编程(九) select 读、写、异常事件发生条件 用select改进回射服务器程序。 15socket编程(十) 用select改进第八章点对点聊天程序 16socket编程(十一) 套接字I/O超时设置方法 用select实现超时 read_timeout函数封装 write_timeout函数封装 accept_timeout函数封装 connect_timeout函数封装 17socket编程(十二) select限制 poll 18socket编程(十三) epoll使用 epoll与select、poll区别 epoll LT/ET模式 19socket编程(十四) UDP特点 UDP客户/服务基本模型 UDP回射客户/服务器 UDP注意点 20socket编程(十五) udp聊天室实现 21socket编程(十六) UNIX域协议特点 UNIX域地址结构 UNIX域字节流回射客户/服务 UNIX域套接字编程注意点 22socket编程(十七) socketpair sendmsg/recvmsg UNIX域套接字传递描述符字 Linux网络编程之进程间通信篇 23进程间通信介绍(一) 进程同步与进程互斥 进程间通信目的 进程间通信发展 进程间通信分类 进程间共享信息的三种方式 IPC对象的持续性 24进程间通信介绍(二) 死锁 信号量 PV原语 用PV原语解决司机与售票员问题 用PV原语解决民航售票问题 用PV原语解决汽车租赁问题 25System V消息队列(一) 消息队列 IPC对象数据结构 消息队列结构 消息队列在内核中的表示 消息队列函数 26System V消息队列(二) msgsnd函数 msgrcv函数 27System V消息队列(三) 消息队列实现回射客户/服务器 28共享内存介绍 共享内存 共享内存示意图 管道、消息队列与共享内存传递数据对比 mmap函数 munmap函数 msync函数 29System V共享内存 共享内存数据结构 共享内存函数 共享内存示例 30System V信号量(一) 信号量 信号量集结构 信号量集函数 信号量示例 31System V信号量(二) 用信号量实现进程互斥示例 32System V信号量(三) 用信号集解决哲学家就餐问题 33System V共享内存与信号量综合 用信号量解决生产者消费者问题 实现shmfifo 34POSIX消息队列 POSIX消息队列相关函数 POSIX消息队列示例 35PO
Linux网络编程(总共41集) 讲解Linux网络编程知识,分以下四个篇章。 Linux网络编程之TCP/IP基础篇 Linux网络编程之socket编程篇 Linux网络编程之进程间通信篇 Linux网络编程之线程篇 Linux网络编程之TCP/IP基础篇 01TCPIP基础(一) ISO/OSI参考模型 TCP/IP四层模型 基本概念(对等通信、封装、分用、端口) 02TCPIP基础(二) 最大传输单元(MTU)/路径MTU 以太网帧格式 ICMP ARP RARP 03TCPIP基础(三) IP数据报格式 网际校验和 路由 04TCPIP基础(四) TCP特点 TCP报文格式 连接建立三次握手 连接终止四次握手 TCP如何保证可靠性 05TCPIP基础(五) 滑动窗口协议 UDP特点 UDP报文格式 Linux网络编程之socket编程篇 06socket编程(一) 什么是socket IPv4套接口地址结构 网络字节序 字节序转换函数 地址转换函数 套接字类型 07socket编程(二) TCP客户/服务器模型 回射客户 /服务器 socket、bind、listen、accept、connect 08socket编程(三) SO_REUSEADDR 处理多客户连接(process-per-conection) 点对点聊天程序实现 09socket编程(四) 流协议与粘包 粘包产生的原因 粘包处理方案 readn writen 回射客户/服务器 10socket编程(五) read、write与recv、send readline实现 用readline实现回射客户/服务器 getsockname、getpeername gethostname、gethostbyname、gethostbyaddr 11socket编程(六) TCP回射客户/服务器 TCP是个流协议 僵进程与SIGCHLD信号 12socket编程(七) TCP 11种状态 连接建立三次握手、连接终止四次握手 TIME_WAIT与SO_REUSEADDR SIGPIPE 13socket编程(八) 五种I/O模型 select 用select改进回射客户端程序 14socket编程(九) select 读、写、异常事件发生条件 用select改进回射服务器程序。 15socket编程(十) 用select改进第八章点对点聊天程序 16socket编程(十一) 套接字I/O超时设置方法 用select实现超时 read_timeout函数封装 write_timeout函数封装 accept_timeout函数封装 connect_timeout函数封装 17socket编程(十二) select限制 poll 18socket编程(十三) epoll使用 epoll与select、poll区别 epoll LT/ET模式 19socket编程(十四) UDP特点 UDP客户/服务基本模型 UDP回射客户/服务器 UDP注意点 20socket编程(十五) udp聊天室实现 21socket编程(十六) UNIX域协议特点 UNIX域地址结构 UNIX域字节流回射客户/服务 UNIX域套接字编程注意点 22socket编程(十七) socketpair sendmsg/recvmsg UNIX域套接字传递描述符字 Linux网络编程之进程间通信篇 23进程间通信介绍(一) 进程同步与进程互斥 进程间通信目的 进程间通信发展 进程间通信分类 进程间共享信息的三种方式 IPC对象的持续性 24进程间通信介绍(二) 死锁 信号量 PV原语 用PV原语解决司机与售票员问题 用PV原语解决民航售票问题 用PV原语解决汽车租赁问题 25System V消息队列(一) 消息队列 IPC对象数据结构 消息队列结构 消息队列在内核中的表示 消息队列函数 26System V消息队列(二) msgsnd函数 msgrcv函数 27System V消息队列(三) 消息队列实现回射客户/服务器 28共享内存介绍 共享内存 共享内存示意图 管道、消息队列与共享内存传递数据对比 mmap函数 munmap函数 msync函数 29System V共享内存 共享内存数据结构 共享内存函数 共享内存示例 30System V信号量(一) 信
教程非常不错,价值280元,绝对是干货 Linux网络编程(总共41集) 讲解Linux网络编程知识,分以下四个篇章。 Linux网络编程之TCP/IP基础篇 Linux网络编程之socket编程篇 Linux网络编程之进程间通信篇 Linux网络编程之线程篇 Linux网络编程之TCP/IP基础篇 01TCPIP基础(一) ISO/OSI参考模型 TCP/IP四层模型 基本概念(对等通信、封装、分用、端口) 02TCPIP基础(二) 最大传输单元(MTU)/路径MTU 以太网帧格式 IC MP ARP RARP 03TCPIP基础(三) IP数据报格式 网际校验和 路由 04TCPIP基础(四) TCP特点 TCP报文格式 连接建立三次握手 连接终止四次握手 TCP如何保证可靠性 05TCPIP基础(五) 滑动窗口协议 UDP特点 UDP报文格式 Linux网络编程之socket编程篇 06socket编程(一) 什么是socket IPv4套接口地址结构 网络字节序 字节序转换函数 地址转换函数 套接字类型 07socket编程(二) TCP客户/服务器模型 回射客户/服务器 socket、bind、listen、accept、connect 08socket编程(三) SO_REUSEADDR 处理多客户连接(process-per-conection) 点对点聊天程序实现 09socket编程(四) 流协议与粘包 粘包产生的原因 粘包处理方案 readn writen 回射客户/服务器 10socket编程(五) read、write与recv、send readline实现 用readline实现回射客户/服务器 getsockname、getpeername gethostname、gethostbyname、gethostbyaddr 11socket编程(六) TCP回射客户/服务器 TCP是个流协议 僵进程与SIGCHLD信号 12socket编程(七) TCP 11种状态 连接建立三次握手、连接终止四次握手 TIME_WAIT与SO_REUSEADDR SIGPIPE 13socket编程(八) 五种I/O模型 select 用select改进回射客户端程序 14socket编程(九) select 读、写、异常事件发生条件 用select改进回射服务器程序。 15socket编程(十) 用select改进第八章点对点聊天程序 16socket编程(十一) 套接字I/O超时设置方法 用select实现超时 read_timeout函数封装 write_timeout函数封装 accept_timeout函数封装 connect_timeout函数封装 17socket编程(十二) select限制 poll 18socket编程(十三) epoll使用 epoll与select、poll区别 epoll LT/ET模式 19socket编程(十四) UDP特点 UDP客户/服务基本模型 UDP回射客户/服务器 UDP注意点 20socket编程(十五) udp聊天室实现 21socket编程(十六) UNIX域协议特点 UNIX域地址结构 UNIX域字节流回射客户/服务 UNIX域套接字编程注意点 22socket编程(十七) socketpair sendmsg/recvmsg UNIX域套接字传递描述符字 Linux网络编程之进程间通信篇 23进程间通信介绍(一) 进程同步与进程互斥 进程间通信目的 进程间通信发展 进程间通信分类 进程间共享信息的三种方式 IPC对象的持续性 24进程间通信介绍(二) 死锁 信号量 PV原语 用PV原语解决司机与售票员问题 用PV原语解决民航售票问题 用PV原语解决汽车租赁问题 25System V消息队列(一) 消息队列 IPC对象数据结构 消息队列结构 消息队列在内核中的表示 消息队列函数 26System V消息队列(二) msgsnd函数 msgrcv函数 27System V消息队列(三) 消息队列实现回射客户/服务器 28共享内存介绍 共享内存 共享内存示意图 管道、消息队列与共享内存传递数据对比 mmap函数 munmap函数 msync函数 29System V共享内存 共享内存数据结构 共享内存函数 共享内存示例 30System V信号量(一) 信号量 信号量

64,637

社区成员

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

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