我编了一个简单的通信程序,C/S模式的,客户端连接服务器接收报文。我希望服务器只和一个客户端连接,就是当一个客户端连接上服务器,其他客户端都不能连,并且如果连接的客户端断开或关闭,立即有新的客户端自动和服务器连接。我看了通信的函数,也看了CSocket等,感觉找不到方向,应该怎么做,期望高手相助!非常感谢!
while (Comm_Flag) {
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )
{
/* Tell the user that we could not find a usable */
/* WinSock DLL. */
return 0;
}
if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 ) {
/* Tell the user that we could not find a usable */
/* WinSock DLL. */
WSACleanup( );
return 0;
}
// 待连接主机IP地址
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr = inet_addr(str_IP); // 本地回路地址,无网卡也可使用;应设为服务器所在主机对应的IP
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(port_num);
// 连接主机
SOCKET sockClient = socket(AF_INET, SOCK_STREAM, 0);
connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));
// 接收信息
char *recvBuf = new char[MessageLen];
recv(sockClient, recvBuf, MessageLen, 0);
CString str;
str.Format("%s", recvBuf);
delete [] recvBuf;
CString OrigMessage = str;
while (Comm_Flag) {
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )
{
/* Tell the user that we could not find a usable */
/* WinSock DLL. */
return 0;
}
if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 ) {
/* Tell the user that we could not find a usable */
/* WinSock DLL. */
WSACleanup( );
return 0;
}
// 待连接主机IP地址
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr = inet_addr(str_IP); // 本地回路地址,无网卡也可使用;应设为服务器所在主机对应的IP
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(port_num);
// 连接主机
SOCKET sockClient = socket(AF_INET, SOCK_STREAM, 0);
connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));
// 接收信息
char *recvBuf = new char[MessageLen];
recv(sockClient, recvBuf, MessageLen, 0);
CString str;
str.Format("%s", recvBuf);
delete [] recvBuf;
CString OrigMessage = str;
那应该把客户端写成非阻塞的?用CSocket写吗?
//拒绝其他链接可以用SOCKET WSAAccept(
SOCKET s,
struct sockaddr FAR* addr,
LPINT addrlen,
LPCONDITIONPROC lpfnCondition,
DWORD dwCallbackData
);
//的第四个参数LPCONDITIONPROC lpfnCondition,如:
static int CALLBACK ConnectAcceptCondition(IN LPWSABUF lpCallerId,
IN LPWSABUF lpCallerData,
IN OUT LPQOS lpSQOS,
IN OUT LPQOS lpGQOS,
IN LPWSABUF lpCalleeId,
OUT LPWSABUF lpCalleeData,
OUT GROUP FAR *g,
IN DWORD dwCallbackData);/*
*接收客户端条件
*/
int CALLBACK CXXX::ConnectAcceptCondition(IN LPWSABUF lpCallerId,
IN LPWSABUF lpCallerData,
IN OUT LPQOS lpSQOS,
IN OUT LPQOS lpGQOS,
IN LPWSABUF lpCalleeId,
OUT LPWSABUF lpCalleeData,
OUT GROUP FAR *g,
IN DWORD dwCallbackData)
{
CXXX* pThis = reinterpret_cast<CXXX*>(dwCallbackData); if(pThis->IsCanConnect) //若没有客户端连接,IsCanConnect你自己定义的BOOL值
return CF_ACCEPT; //接受连接
else
return CF_REJECT; //拒接连接
}//接收客户端时
SOCKADDR_IN ClientAddr;
int serAddrLen = sizeof(ClientAddr);
sAccept=WSAAccept(sListen,
(SOCKADDR*)&ClientAddr,
&serAddrLen,
ConnectAcceptCondition,
(DWORD)m_xxx);//CXXX的指针 if (INVALID_SOCKET==sAccept)
continue;