大家都知道网络编程有异步非租塞方式,同步租塞方式,同步租塞方式逻辑简单,异步非租塞方式编程复杂.很多的C/S模式大都采用异步非租塞方式,在网络上也有大量的例子程序,而对于同步租塞方式却很少,下面代码为同步租塞方式予以参考:
注:服务器也使用的是同步方式
SOCKET sock;
WSADATA WSAData;
sockaddr_in addr;
int len=sizeof(sockaddr_in);
std::string strBuff = _T("");
std::string strSend = _T("");
int iReadLen = 0;
if(WSAStartup(MAKEWORD(2,2), &WSAData)!=0)
{
printf("WSAStartup error!/n");
return ;
}
if((sock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==INVALID_SOCKET)
{
printf("socket error!/n");
return ;
}
//设置为同步阻塞方式
ULONG ulArg=0;
int iRet = ioctlsocket(sock,FIONBIO,&ulArg);
//设置接受超时时间
int iRcvTimeOut = 5000; //5秒
setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(char*)&iRcvTimeOut,sizeof(int));
BOOL bl = TRUE;
setsockopt( sock , IPPROTO_TCP, TCP_NODELAY , (const char*)&bl, sizeof(BOOL));
setsockopt( sock , IPPROTO_TCP, SO_KEEPALIVE, (const char*)&bl, sizeof(BOOL));
addr.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
addr.sin_addr.S_un.S_addr= inet_addr("211.138.113.137");
addr.sin_family=AF_INET; //使用TCP/IP协议
addr.sin_port=htons(8039); //客户端指定的IP地址
int nConnect=connect(sock,(LPSOCKADDR)&addr,sizeof(addr)); //请求连接
if (nConnect == 0)
{
//打包的数据
strSend = MakeSendPhones();
//send data to server
int iSend = send(sock,strSend.c_str,strSend.size(),MSG_OOB);
int iRead = 0;
char szBuff[1025] = {0};
char szTempBuff[1025] = {0};
while (1)
{
memset(szBuff,0,1025);
memset(szTempBuff,0,1025);
//接收数据还可以用WSARecvEx(),如下注释部分
//int iFlag = 0;
// iRead = WSARecvEx(sock,szBuff,1024, &iFlag);
//注意我使用MSG_PEEK MSG_OOB都接收不到数据
iRead = recv(sock,szBuff,1024,0);
if (iRead > 0)
{
memcpy(szTempBuff,szBuff,iRead);
strBuff = strBuff + szTempBuff;
iReadLen += iRead;
}
else if (iRead == 0)
{
break;
}
else
{
int nErro = WSAGetLastError();
break;
}
}
}
int iClose = closesocket(sock);
WSACleanup();