看了《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个。