关于Socket I/O模型探讨(TCP和UDP系列问题)

24 views
Skip to first unread message

fhq...@hotmail.com

unread,
Jan 9, 2007, 9:26:01 PM1/9/07
to 网络通信架构&技术
楼主ychener(贫血)2002-05-24 17:23:44 在 VC/MFC / 基础类
提问
本身Socket技术是协议无关的,可是我在开发Socket程序时有些问题不是很清楚。

看了《Windows
网络编程技术》书中讲的也不是很明了。


问题1:Socket的WSAsyncSelect模型(异步消息I/O模型)是不是针对TCP协议的,对于UDP协议是不使用的,就是说UDP协议是没有消息通知的

对不对?为什么?Socket的WSAEventSelect模型(异步事件I/O模型)是否也是一样?


问题2:对于Win32平台下Socket的Overlapper
I/O模型是否对UDP协议可用,如何使用?

问题3:本人在写TCP协议的Socket程序时,对于服务器端应该是有一个客户端的Socket的列表,而且这个Socket的列表是必须存在的,否则就

无法同每个客户端进行信息交换,但是对于UDP协议是不需要的,服务器端只要记录下每个客户端建立UDP
Socket的Port和IP即可,这样的话在


服务器端就不像TCP需要维护客户端的Socket列表,不知这种说法对不?


问题点数:100、回复次数:14
Top


1 楼rick1126()回复于 2002-05-24 17:40:06 得分 0
使用WSAJoinLeaf可以进行IP Multicast,
这样在内部网里面就可以实现客户端规模无关的数据广播.
至于WSAEventSelect我想其实是对于select的异步扩展,
实际应用当中你不必对于每一个SOCKET调用select,
而这和具体Windows的消息无关.
Top

2 楼YauYuk()回复于 2002-05-24 17:40:27 得分 0 hehe....i
dont know

but i up
Top

3 楼ychener(贫血)回复于 2002-05-24 17:51:51 得分 0
Socket的WSAEventSelect是对Event的内核对象进行标记,来通知别的线程的,这个我知道,但是我的想知道的是这个IO模型是否对UDP协议可用,具体如何用,至于IP多播的多播地址是一个D类网地址,在intel网上实现是有问题的。

Top

4 楼anyiflyer(Jerry)回复于 2002-05-24 18:13:25 得分
40问题一:使用UDP协议通信,仍然可以有事件通知,例如:

iRet=WSAAsyncSelect(m_RecvSock,m_hWnd,WM_ON_RECV,FD_READ);

其中m_hWnd是处理WM_ON_RECV消息的窗口句柄,WM_ON_RECV是自定义消息类型

#define WM_ON_RECV WM_USER + 0x100

//mainfrm.cpp在MainFrm的消息映射宏中加上,假设OnRecv是WM_ON_RECV
消息处理函数
m_hWnd = CMainFrame::GetSafeHwnd(),
IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
//{{AFX_MSG_MAP(CMainFrame)
//}}AFX_MSG_MAP
ON_MESSAGE(WM_ON_RECV,OnRecv)
END_MESSAGE_MAP()
//mainfrm.h
class CMainFrame : public CFrameWnd
{ 略......
// Generated message map functions
protected:
//{{AFX_MSG(CMainFrame)
//}}AFX_MSG
afx_msg LRESULT OnRecv(DWORD wParam,DWORD lParam);//加上它

DECLARE_MESSAGE_MAP()
};
问题3:
在服务端,你可以从CAsyncSocket继承一个CServerSocket
并重载CAsyncSocket的OnReceive方法,
void CRecvSocket::OnReceive(int nErrorCode)
{
char buff[Max_Data_Length] ;
int nRead ;
CString srcIP ;
UINT srcPort ;

nRead = ReceiveFrom(buff,Max_Data_Length, srcIP,
srcPort);
//下略......
}
srcIP,srcPort中就是发送端的IP地址跟Port号

Top

5 楼lijian6185(秋叶禅)回复于 2002-05-24 18:22:53 得分 0
对于楼上的:

如果这样的话,是否一样要维护一个保存IP地址和PORT号的列表呢?


多个客户端,每一个客户端都有IP地址,PORT号的。你不是一样要保存吗?
Top

6 楼snake1122(surfer)回复于 2002-05-24 18:27:32 得分 0
难道不需要保存吗?
Top

7 楼lijian6185(秋叶禅)回复于 2002-05-24 18:37:57 得分 0
而且你那只是接收,接收也可以不用ReceiveFrom(),直接用Receive()


如果要发送的话,还是要一个列表一维护客户端.不知道有什么办法,可以不用维护,否则万个客户端,你就得轮询一万次!
Top

8 楼edrftgyh(老胡)回复于 2002-05-24 18:42:00 得分 0 up
Top

9 楼mygo(舟中夜起)回复于 2002-05-24 22:11:59 得分
60问题一:UDP用WSAsyncSelect没有问题,我一直用它


问题二:UDP重叠模型没有问题,用WSASocket创建套接字,收发用WSASendTo和WSARecvFrom,不建议使用,移植性太差

问题三:由于UDP是非连接的,不需要对每个请求都要开一个套接字,来一个包处理一个就可以了,不管是哪里来的,只要是同一端口,所以一个套接字就可以了
Top

10 楼ychener(贫血)回复于 2002-05-25 00:03:47 得分 0
对于UDP协议用一个UDP
SOCKET对多个客户端进行轮循发送同样的数据,效率会不会不高?而且不易使用多线程,因为实际上一个SOCKET是一个临界量!


如果对应每个客户端都建立一个UDP
SOCKET可能资源会占用多一些,但是却很容易实现多线程来提高效率,每个线程管理一些UDP
SOCKET进行发送数据。

不知道我说的对不对?望给予回复!
Top

11 楼ychener(贫血)回复于 2002-05-25 01:49:33 得分 0
还有就是如果用异步Socket的话,UDP协议在发送数据的时候也是会出现

WSAEWOULDBLOCK错误的吗?
Top

12 楼Hover(翔)回复于 2002-05-25 02:33:09 得分 0
到此一游...

以脚印为证
Top

13 楼mygo(舟中夜起)回复于 2002-05-25 13:05:21 得分 0 to
ychener(贫血) :
你把简单的问题想的太深奥了


套接字只是一个用于标示收发数据的东西,你想模拟广播方式发送数据,只要每次收到一个发送准备好的消息,就可以发送,根据我的经验,多线程发送和循环发送效率差不多。


还有,对于UDP来说,你没有办法为每个客户端建立一个socket,因为bind只能一个地址,而且也没有accept之类的东西,非面向连接。一般来说,对于压力比较的服务器,来一个数据包,就开一个线程处理,处理完了就结束线程,最好限制一下线乘数目,例如200个。

Reply all
Reply to author
Forward
0 new messages