《Windows网络编程技术》是全世界实用性最差的书!!!!! 有同感者请UP! 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 TransmitFile怎么用,我指有很多文件要传? 不UP者请贴出一段用WSAAsyncSelect或WSAEventSelect模型做的具有实用价值的多连接代码(更复杂的Overlapped或Completion Port就算了)。我出1000分! Why do you say it? 我定义一个对象:CIOCPClient,有两个socket(始终跟server连接)其他不用解析了吧,应该看的懂,要Completion Port的,我也有,《Windows网络编程技术》深入程度不够,但是面广InitClient(){ ... m_hThread=(HANDLE)_beginthreadex(NULL,0,SocketThreadProc,...) ...初始化m_hSocket1和m_hSocket2 int nRet1 = WSAEventSelect (m_hSocket1,m_hEvent1,FD_CONNECT|FD_CLOSE|FD_READ); int nRet2 = WSAEventSelect (m_hSocket2,m_hEvent2,FD_CONNECT|FD_CLOSE|FD_READ);}unsigned CIOCPClient::SocketThreadProc(LPVOID lParam){ CIOCPClient* pThis = reinterpret_cast<CIOCPClient*>(lParam); SOCKET SocketArray[2]; WSAEVENT EventArray[3];// DWORD Index; SocketArray[0] = pThis->m_hSocket1; SocketArray[1] = pThis->m_hSocket2; EventArray[0] = pThis->m_hEvent1; EventArray[1] = pThis->m_hEvent2; EventArray[2] = pThis->m_hKillEvent; WSANETWORKEVENTS events; bool bExit = false; while(!bExit) { // // Wait for something to happen DWORD dwIndex; dwIndex = WSAWaitForMultipleEvents(3, EventArray, FALSE,100,FALSE); int err = GetLastError(); if (dwIndex == WSA_WAIT_TIMEOUT) continue; if(dwIndex == WAIT_OBJECT_0 + 2) break; // // Figure out what happened // int nRet = WSAEnumNetworkEvents( SocketArray[dwIndex - WAIT_OBJECT_0], EventArray[dwIndex - WAIT_OBJECT_0], &events); if(events.lNetworkEvents & FD_CONNECT) { ......... } if(events.lNetworkEvents & FD_READ) { if(events.iErrorCode[FD_READ_BIT] != 0) break; else { char temp[1024]; int length = recv (SocketArray[dwIndex - WAIT_OBJECT_0],temp,1024,0); temp[length] = '\0'; } } if(events.lNetworkEvents & FD_CLOSE) { char temp[100] = "Client Closed"; if(events.iErrorCode[FD_CLOSE_BIT] != 0) break; else { closesocket(SocketArray[dwIndex - WAIT_OBJECT_0]); SocketArray[dwIndex - WAIT_OBJECT_0] = INVALID_SOCKET; } } } // while.... return 0; // Normal Thread Exit Code...} 我敢保证 Bind 是全世界最不佩谈实用性的人! 我敢打赌, Bind 是世界上最不佩谈实用性的人 呵呵,我感觉Bind可能是气话,因为我在csdn见过他几面。好像他也有提出这方面的问题?呵呵,我听了当然感觉很不爽,我是看 《Windows网络编程技术》 书长大的,一听,当然很火。 一个实用的模型至少应该是这样的:SERVER:可随时接受多个连接,连接数不固定。对每个连接可随时发送和接收大量数据;可随时关闭某个连接。请分析该书中的例子(大致如楼上所贴):1、现有10个数据包要发送给客户A,另有8个数据包发送给客户B,如何发送?在哪作调用?调用哪个函数?如果某次的send返回只是发送数据的一部分怎么办?2、现想关闭客户B,如何调用?在哪调用? 我极力推荐大家看《tcp/ip详解卷1:协议》,这本有深度,不适合初学者。我刚学socket编程的时候,今年3月份,也拿起那本书啃,但是难以下咽,于是放弃。直到最近一个月,在这方面出现了很多问题以后,我带着问题去找原理,感觉收获颇丰。呵呵,好书共欣赏! 容易:在服务器你自己定义一个struct IpSock{ string m_strIp1;(或者保存客户名等等) SOCKET m_hSocket1;}然后定义一个链表,将连接上的socket存到里面去CList<IpSock,IpSock&> m_listIpSock;每次发数据给客户A,先搜寻客户A的socketA,然后跟socketA相通讯就可以了关闭客户B:先搜寻客户B的socketB,然后shutdown(),closesocket(),这样就会触发相应的客户端的m_socket2的ON_CLOSE事件,然后问题就解决了如果某次的send返回只是发送数据的一部分怎么办?用while循环发送 yanhuahui(眼发黑):在CSDN和VCHELP咱们都多次见过。我说得不好请不要介意。首先你说的办法我全都试过,我原先的设想的模式也和你几乎一模一样。下面我分析给你看:1、假设m_sockLink是主线程的成员,在线程A中有数据要发送,调用m_sockLink的发送函数SendData,int CMySocket::SendData(LPVOID pData, int nDataLength){ .... while(nResult < nDataLength){ nResult = send(m_hSocket, pData + nOffet, nDataLength - nOffet, 0); if(nResult == SOCKET_ERROR){ int nError = WSAGetLastError(); if(nError == WSAEWOULDBLOCK){ break; } else{ ... } ... } }}某次send的返回为WSAEWOULDBLOCK,此时调用返回,由SocketThreadProc处理FD_WRITE事件。在这时又有新数据发送线程调用SendData,而此时FD_WRITE事件正在处理,请问:客户接收到的数据是什么?2、服务端关闭客户B的连接,在shutdown和closesocket之后,还能响应FD_CLOSE吗? 呵呵,vchelp我现在都不怎么去了某次send的返回为WSAEWOULDBLOCK,此时调用返回,由SocketThreadProc处理FD_WRITE事件。在这时又有新数据发送线程调用SendData,而此时FD_WRITE事件正在处理,请问:客户接收到的数据是什么?上面你说的这些是不是针对那本书上的例子?你服务器采用什么模式,我做的服务器是完成端口,客户端是异步事件模式,冗余网络,两条线连接,里面有四个程序,原先因为打包太大,所以没有给想要的兄弟。如果你要的话,我就分多次发给你,我那个就可以解决那个问题。2、服务端关闭客户B的连接,在shutdown和closesocket之后,还能响应FD_CLOSE吗?我觉得这个很显然的说实在select模型我不是很熟,对FD_WRITE事件我也茫然,不知哪位高手出来讲讲,知识共享,能够解决我,我的茫然说白了就是:需要调用FD_WRITE的一般都是用到什么场合,有一个我知道,比如用在代理上,将收到的数据直接发送到另一个端口去。其他我都不用FD_WRITE,直接调用send函数,不知我的想法对不对,希望大侠们给我解释。到时我会给分的, 向父窗体的列表控件增加列表 两个线程能否同时操作一个视图 新添加的接口,在delphi中不能访问,有没有人遇到过?200分奉上 很让我头疼的问题,请兄弟们帮忙看一下,想了很久,也不知其所以然!!! 如何把文件写到硬盘上,windows下看不见,但能读到 关于CString的一个问题 关于键盘钩子 问题:通过分析磁盘结构直接读写FAT/FAT32/NTFS文件系统文件 TCP/IP协议下互传数据堵塞问题如何解决呢?请赐教 怎么实现多语言功能? 怎样将不同的对话框放在一个数组中-----(在线等待) 高分求一画弧的算法
InitClient()
{
...
m_hThread=(HANDLE)_beginthreadex(NULL,0,SocketThreadProc,...)
...初始化m_hSocket1和m_hSocket2
int nRet1 = WSAEventSelect
(m_hSocket1,m_hEvent1,FD_CONNECT|FD_CLOSE|FD_READ);
int nRet2 = WSAEventSelect
(m_hSocket2,m_hEvent2,FD_CONNECT|FD_CLOSE|FD_READ);
}
unsigned CIOCPClient::SocketThreadProc(LPVOID lParam)
{ CIOCPClient* pThis = reinterpret_cast<CIOCPClient*>(lParam);
SOCKET SocketArray[2];
WSAEVENT EventArray[3];// DWORD Index; SocketArray[0] = pThis->m_hSocket1;
SocketArray[1] = pThis->m_hSocket2; EventArray[0] = pThis->m_hEvent1;
EventArray[1] = pThis->m_hEvent2;
EventArray[2] = pThis->m_hKillEvent; WSANETWORKEVENTS events; bool bExit = false;
while(!bExit)
{
//
// Wait for something to happen
DWORD dwIndex;
dwIndex = WSAWaitForMultipleEvents(3,
EventArray, FALSE,100,FALSE); int err = GetLastError();
if (dwIndex == WSA_WAIT_TIMEOUT)
continue;
if(dwIndex == WAIT_OBJECT_0 + 2)
break; //
// Figure out what happened
//
int nRet = WSAEnumNetworkEvents(
SocketArray[dwIndex - WAIT_OBJECT_0],
EventArray[dwIndex - WAIT_OBJECT_0], &events);
if(events.lNetworkEvents & FD_CONNECT)
{
.........
} if(events.lNetworkEvents & FD_READ)
{
if(events.iErrorCode[FD_READ_BIT] != 0)
break;
else
{
char temp[1024];
int length = recv
(SocketArray[dwIndex - WAIT_OBJECT_0],temp,1024,0);
temp[length] = '\0';
}
}
if(events.lNetworkEvents & FD_CLOSE)
{
char temp[100] = "Client Closed";
if(events.iErrorCode[FD_CLOSE_BIT] != 0)
break;
else
{
closesocket(SocketArray[dwIndex - WAIT_OBJECT_0]);
SocketArray[dwIndex - WAIT_OBJECT_0] = INVALID_SOCKET;
}
}
} // while.... return 0; // Normal Thread Exit Code...
}
在服务器你自己定义一个
struct IpSock
{
string m_strIp1;(或者保存客户名等等)
SOCKET m_hSocket1;
}
然后定义一个链表,将连接上的socket存到里面去
CList<IpSock,IpSock&> m_listIpSock;
每次发数据给客户A,先搜寻客户A的socketA,然后跟socketA相通讯就可以了
关闭客户B:先搜寻客户B的socketB,然后shutdown(),closesocket(),这样就会触发相应的客户端的m_socket2的ON_CLOSE事件,然后问题就解决了如果某次的send返回只是发送数据的一部分怎么办?
用while循环发送
{
....
while(nResult < nDataLength){
nResult = send(m_hSocket, pData + nOffet, nDataLength - nOffet, 0);
if(nResult == SOCKET_ERROR){
int nError = WSAGetLastError();
if(nError == WSAEWOULDBLOCK){
break;
}
else{
...
}
...
}
}
}某次send的返回为WSAEWOULDBLOCK,此时调用返回,由SocketThreadProc处理FD_WRITE事件。在这时又有新数据发送线程调用SendData,而此时FD_WRITE事件正在处理,请问:客户接收到的数据是什么?2、服务端关闭客户B的连接,在shutdown和closesocket之后,还能响应FD_CLOSE吗?
某次send的返回为WSAEWOULDBLOCK,此时调用返回,由SocketThreadProc处理FD_WRITE事件。在这时又有新数据发送线程调用SendData,而此时FD_WRITE事件正在处理,请问:客户接收到的数据是什么?
上面你说的这些是不是针对那本书上的例子?你服务器采用什么模式,我做的服务器是完成端口,客户端是异步事件模式,冗余网络,两条线连接,里面有四个程序,原先因为打包太大,所以没有给想要的兄弟。如果你要的话,我就分多次发给你,我那个就可以解决那个问题。2、服务端关闭客户B的连接,在shutdown和closesocket之后,还能响应FD_CLOSE吗?
我觉得这个很显然的说实在select模型我不是很熟,对FD_WRITE事件我也茫然,不知哪位高手出来讲讲,知识共享,能够解决我,我的茫然说白了就是:需要调用FD_WRITE的一般都是用到什么场合,有一个我知道,比如用在代理上,将收到的数据直接发送到另一个端口去。其他我都不用FD_WRITE,直接调用send函数,不知我的想法对不对,希望大侠们给我解释。到时我会给分的,