![]() |
#2
yuccn2014-06-23 13:54
|

WSAData wsaDate; //声明一个WSADate结构体(包含了Winsock库的版本信息)变量
int nRet=WSAStartup(MAKEWORD(2,2),&wsaDate); //初始化该结构体(协商版本) 若返回0则成功
//if(nRet!=0)
//错误处理
sockaddr_in saServer; //声明一个地址结构体 sockaddr是系统自己使用的
saServer.sin_family=AF_INET; //必须是AF_INET
saServer.sin_port=htons(10000); //必须转换成网络字节序 htonl/htons (host to net long/ short)
saServer.sin_addr.s_addr=htonl(INADDR_ANY); //接收任意IP的数据 (通配地址) //数字是short 字符long
SOCKET sasocket; //声明一个套接字句柄变量
sasocket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);//使用UDP时的参数SOCK_DGRAM IPPROTO_UDP
bind(sasocket,(sockaddr*)&saServer,sizeof(saServer));//绑定成功返回0 否则SOCK_ERROR
listen(sasocket,1);//backlog表示可以接受的客服请求的最大数量 监听成功返回0 SOCK_ERROR
sockaddr_in saClient; //客服端的地址结构体
int nsaClient=sizeof(sockaddr); //客服端地址信息的大小
SOCKET hClientsocket=accept(sasocket,(sockaddr*)&saClient,&nsaClient);//接收客服端的连接请求
//返回的套接字将用于与这个客服的连接 sasocket可以继续接受其他客服请求
//如果请求队列为空 那么将被阻塞 失败返回INVALID_SOCKET
const int buff_len=1024;
char recvbuff[buff_len+1];
nRet=recv(hClientsocket,recvbuff,buff_len,0);//返回接收数据的实际大小 失败返回SOCKET_ERROR flags参数有MSG_PEEK MSG_OOB 或一起使用
//如果系统能接收的最大数据量为len 那么recv将返回len 但不能超过buff_len
//如果系统缓存区满了 那么调用recv的线程将被阻塞(停止运行) ,直到系统可以接收数据
//************确保接收(发送)全部数据********************************************************
int nbuff_len=520;//假设要接受的数据大小为520
int nn=0;
while(nbuff_len>0)
{
int ret=recv(hClientsocket,&recvbuff[nn],nbuff_len,0);
//nn在增加 nbuff_len在递减
if(ret=SOCKET_ERROR) //发送失败 就这一种情况
{
//错误处理
}
else
if(ret==0)
{
//连接被发送方关闭,错误处理
}
nn+=ret;
nbuff_len-=ret;
}
//**********************************************************************************************
int nSend=send(hClientsocket,recvbuff,nRet,0);//把接收到的实际数据的大小发送出去 flags参数有MSG_DONTROUTE MSG_OOB 或一起使用
//nRet不能超过系统接收的最大长度 SOCKET_ERROR
//
shutdown(hClientsocket,SD_SEND);//SOCKET_ERROR 如果是UDP 此操作不需要 因为每次发送(接收)的都是完整的数据报
//shutdown之后还在接收数据
//do
//{ 数据流还在流向接收端直到全部到达
//ret=recv(hClientsocket,&recvbuff[nn],nbuff_len,0);
//}while(ret!=0)
//如果ret==0了
closesocket(hClientsocket);//SOCKET_ERROR
WSACleanup();//清除关于winsock的一切资源
int nRet=WSAStartup(MAKEWORD(2,2),&wsaDate); //初始化该结构体(协商版本) 若返回0则成功
//if(nRet!=0)
//错误处理
sockaddr_in saServer; //声明一个地址结构体 sockaddr是系统自己使用的
saServer.sin_family=AF_INET; //必须是AF_INET
saServer.sin_port=htons(10000); //必须转换成网络字节序 htonl/htons (host to net long/ short)
saServer.sin_addr.s_addr=htonl(INADDR_ANY); //接收任意IP的数据 (通配地址) //数字是short 字符long
SOCKET sasocket; //声明一个套接字句柄变量
sasocket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);//使用UDP时的参数SOCK_DGRAM IPPROTO_UDP
bind(sasocket,(sockaddr*)&saServer,sizeof(saServer));//绑定成功返回0 否则SOCK_ERROR
listen(sasocket,1);//backlog表示可以接受的客服请求的最大数量 监听成功返回0 SOCK_ERROR
sockaddr_in saClient; //客服端的地址结构体
int nsaClient=sizeof(sockaddr); //客服端地址信息的大小
SOCKET hClientsocket=accept(sasocket,(sockaddr*)&saClient,&nsaClient);//接收客服端的连接请求
//返回的套接字将用于与这个客服的连接 sasocket可以继续接受其他客服请求
//如果请求队列为空 那么将被阻塞 失败返回INVALID_SOCKET
const int buff_len=1024;
char recvbuff[buff_len+1];
nRet=recv(hClientsocket,recvbuff,buff_len,0);//返回接收数据的实际大小 失败返回SOCKET_ERROR flags参数有MSG_PEEK MSG_OOB 或一起使用
//如果系统能接收的最大数据量为len 那么recv将返回len 但不能超过buff_len
//如果系统缓存区满了 那么调用recv的线程将被阻塞(停止运行) ,直到系统可以接收数据
//************确保接收(发送)全部数据********************************************************
int nbuff_len=520;//假设要接受的数据大小为520
int nn=0;
while(nbuff_len>0)
{
int ret=recv(hClientsocket,&recvbuff[nn],nbuff_len,0);
//nn在增加 nbuff_len在递减
if(ret=SOCKET_ERROR) //发送失败 就这一种情况
{
//错误处理
}
else
if(ret==0)
{
//连接被发送方关闭,错误处理
}
nn+=ret;
nbuff_len-=ret;
}
//**********************************************************************************************
int nSend=send(hClientsocket,recvbuff,nRet,0);//把接收到的实际数据的大小发送出去 flags参数有MSG_DONTROUTE MSG_OOB 或一起使用
//nRet不能超过系统接收的最大长度 SOCKET_ERROR
//
shutdown(hClientsocket,SD_SEND);//SOCKET_ERROR 如果是UDP 此操作不需要 因为每次发送(接收)的都是完整的数据报
//shutdown之后还在接收数据
//do
//{ 数据流还在流向接收端直到全部到达
//ret=recv(hClientsocket,&recvbuff[nn],nbuff_len,0);
//}while(ret!=0)
//如果ret==0了
closesocket(hClientsocket);//SOCKET_ERROR
WSACleanup();//清除关于winsock的一切资源
学习笔记分享下
