关于SOCKET线程池,多个线程可否对同一个套接字同时写操作等问题?

hearthavegone 2005-04-13 02:38:17
最近在做一个服务器端的程序,遇到一系列的问题,请各位指导

开发环境:win2000,VC6,网络环境:通过互联网进行连接
开发思路:采用winsock1.1,及多线程的并发服务器,每个连接上来时,产生一个线程与其进行通信

1.多个线程可否对同一个套接字进行写操作,例如有一个SOCKET s;两个线程同时向s中写入内容,其中
一个写入为"12",而另一个写入内容为"34",在客户端接收的数据中有没有可能结果为"13","24"???
即收到的内容发生错乱???如果错乱则说明操作系统在发送时没有进行同步,此时在发送时我就要自
己进行同步了(背景是子线程负责与s进行通信,但主线程在某个时刻可能也需要向s发送一条通知消息)

2.关于线程池的问题:小弟线对程池思想基本有所了解,我先讲一下我的思路,采用线程预分配技术,
如首先预分配10个子线程等待连接,并且建立一个链表,该链表存放accept后返回的与客户端对等的套
接字,在对该链表进行添加,删除操作的时候需要用互斥体进行同步,负责处理accept请求的线程向该
链表中添加套接字节点,同时向等待的线程发送事件通知,要求其从链表中读取可用的套接字,并且为
之提供服务。当子线程负责的套接字断开时,该子线程被挂起,等待事件通知。但问题是,如果有许多
子线程,那企不是要创建很多个事件对象,会不会导致服务器性能上出现下降。

3.发送大的数据包的问题:当客户端登录后,会向服务器发送清求要求返回所有客户信息,而客户信息则
为一个结构,一般情况当单个客户信息填满后,可能有300个byte左右,在这种情况下,我应该如何组织
客户信息包呢,是每个数据包中只包含一个客户信息呢,还是每个数据包中包含10条客户信息包呢,还
是更多呢????我个人的意思是,由于TCP是基于流的协议,本身就是没有边界的,所以数据包是尽量
大些为好,可以提高每次发送的效率,如send一次发送5K左右,大概18个左右的客户信息结构(300 * 17
),这样做是否合适????

4.最后一个问题比较低级,是个客户端编程的问题:举例来说,就是客户端有多个类型的对话框都包含
同一个相同的请求(当然同一个对话框中可能有多个不同类型的请求),如用户登录后,可能会打开某个
对话框,该对话框中有一个列表框,和一个“获取客户信息”的按钮,当用户点击此按钮时,需要向服
务器发送请求获取所有客户信息,然后要在列表框中显示出来,而问题是,当用户请求的数据返回时,
我如何根据这条返回的消息找到相应显示这个数据包内容的窗口,他们之间应该如何建立关连???并
且数据返回时,该对话框窗口可能已经关闭了.
...全文
1416 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
hearthavegone 2005-04-25
  • 打赏
  • 举报
回复
多谢几位,结帐!
IloveAzhu 2005-04-22
  • 打赏
  • 举报
回复
gz
Practise_Think 2005-04-16
  • 打赏
  • 举报
回复
多个线程可以同时操作同一个SOCKET但要注意安全!!
lianglp 2005-04-16
  • 打赏
  • 举报
回复
多谢两位帮忙,现在关键的还是第一个问题,因为没有办法对单个套接字的写进行同步,因为实现起来很困难,也比较麻烦,
=================================================================================>
楼主可以试着用mutex进行,
如下就可实现:

int __stdcall SendData(SOCKET sk,char* pBuffer,DWORD dwSize)
{
TCHAR szMutexName[MAX_PATH] = {"__SocketSendMutexName"};
int nLen = ::lstrlen(szMutexName);
::atoi(::GetCurrentProcessId(),szMutexName+nLen,10);
nLen = ::lstrlen(szMutexName);
::atoi(sk,szMutexName+nLen,10);

HANDEL hMutext = ::CreateMutex(...,szMutexName);//创建本进程内唯一socket发送互拆
::WaitForSingleObject(hMutex,INFINITE);

int nResult = ::send(sk,pBuffer,dwSize,NULL);//发送数据

::ReleaseMutex(hMutex);
::CloseHandle(hMutex);

return nResult;
}
licry01 2005-04-15
  • 打赏
  • 举报
回复
(1) 不会出现 13 ,24 这样的情况的
第一个线程send,会产生一个tcpid之类的东东,即使发送到一半,控制权给了线程2,线程2send后又有自己的tcpid,据TCP/IP协议,最后IP重组后得的数据依然还是 12 ,34

解决思路: 你在对socket操作之前,先select一下,检查它是否可操作,然后再操作它
select的用法可查msdn
llm06 2005-04-14
  • 打赏
  • 举报
回复
自己同步一下吧。
不要同时读或者同时写
zhaohonghua 2005-04-14
  • 打赏
  • 举报
回复
原则上说是有可能的
但是实际上的可能性很小
你可以试试发个长一点的,比如一个发1024字节个'a'
一个发1024字节个'b'
看看收到的a和b是不是分开的
hearthavegone 2005-04-14
  • 打赏
  • 举报
回复
多谢两位帮忙,现在关键的还是第一个问题,因为没有办法对单个套接字的写进行同步,因为实现起来很困难,也比较麻烦,(但可以对所有的套接字进行同步,只需要一个函数就可以了,但可能导致效率不高),我查了很多资料,也没有哪本资料对以下的结果进行说明:

例如有一个SOCKET s;两个线程同时向s中写入内容,其中
一个写入为"12",而另一个写入内容为"34",在客户端接收的数据中有没有可能结果为"13","24"???
halfdream 2005-04-14
  • 打赏
  • 举报
回复
1,需要自己处理同步。
3,可以
4,这只是你客户端交互设计的问题,比如用户主动关键窗口,意味放弃去读返回数据,返回的数据找不到对应窗口,扔掉就是。
zhaohonghua 2005-04-13
  • 打赏
  • 举报
回复
1、多个线程可以对同一socket进行收发,但是要自己进行同步

2、既然是线程池,那么就不应该有太多的线程,否则就失去了线程池的意义
同步是难免的,如果线程的处理过程比较长的话实际上互斥的可能性不是很多,因为毕竟线程的数目也不多,而且从链表或者队列里添加、删除是很快的

3、一般来说是大点好
4、应用程序控制的,你应该对窗口的打开、关闭进行控制,加以处理
晨星 2005-04-13
  • 打赏
  • 举报
回复
(1)不会同步。socket本来也没有什么同步。同步机制完全是根据程序逻辑的需求。

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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