回射程序3(服务器)——客户服务器不定长接收数据

来源:互联网 发布:360驱动大师mac版 编辑:程序博客网 时间:2024/05/17 04:46

设计思路上一篇已经说明。

贴上服务器的代码:

// 回显服务器3.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include <stdio.h>#include <stdlib.h>#include <winsock2.h>#include <string.h>#pragma comment(lib,"wsock32.lib")#define  SERVERPROT 6000#define  MAXSIZE 100//函数声明int recvn(SOCKET s, char * recvbuf, unsigned int fixedlen);int recvvl(SOCKET s, char * recvbuf, unsigned int recvbuflen);int _tmain(int argc, _TCHAR* argv[]){//初始化WinSockWSADATA wsaData;int ret = WSAStartup(MAKEWORD(2,2),&wsaData);if(ret!=0){printf("WSAStartup() failed!code:%d\n",WSAGetLastError());return -1;}if(LOBYTE(wsaData.wVersion)!=2||HIBYTE(wsaData.wVersion)!=2){WSACleanup();printf("Invalid WinSock Version\n");return -1;}//创建监听套接字SOCKET slisten;slisten = socket(AF_INET,SOCK_STREAM,0);if(slisten == INVALID_SOCKET){printf("socket() failed!code:%d\n",WSAGetLastError());WSACleanup();return -1;}//构建服务器本地地址信息struct sockaddr_in serveraddr;serveraddr.sin_family = AF_INET;serveraddr.sin_port = htons(SERVERPROT);serveraddr.sin_addr.S_un.S_addr =  INADDR_ANY;//绑定ret = bind(slisten,(sockaddr*)&serveraddr,sizeof(serveraddr));if(ret == SOCKET_ERROR){printf("bind() failed!code:%d\n",WSAGetLastError());closesocket(slisten);WSACleanup();return -1;}//侦听连接请求ret = listen(slisten,5);if(ret == SOCKET_ERROR){printf("listen() failed!code:%d\n",WSAGetLastError());closesocket(slisten);WSACleanup();return -1;}printf("waiting for client connecting...\n");//接收客户端连接struct sockaddr_in clientaddr;int clientaddrlen = sizeof(clientaddr);SOCKET sServer;//连接套接字char buff[MAXSIZE];//接收缓存char sendbuf[MAXSIZE];//发送缓存unsigned int slen=0; //发送数据长度unsigned int buflen=MAXSIZE;sServer = accept(slisten,(struct sockaddr*)&clientaddr,&clientaddrlen);if(sServer == INVALID_SOCKET){printf("accept() failed!code:%d\n",WSAGetLastError());closesocket(slisten);WSACleanup();return -1;}while(TRUE)  //循环接收数据{memset(buff, 0 , MAXSIZE);memset(sendbuf,0,MAXSIZE);ret = recvvl(sServer,buff,buflen);if(ret==SOCKET_ERROR){int nErrCode = WSAGetLastError();//错误代码if (WSAENOTCONN == nErrCode){printf("The socket is not connected!\n");}else if(WSAESHUTDOWN == nErrCode){printf("The socket has been shut down!\n");}else if (WSAETIMEDOUT == nErrCode){printf("The connection has been dropped!\n");}else if (WSAECONNRESET == nErrCode){printf("The virtual circuit was reset by the remote side!\n");}else{}closesocket(sServer);closesocket(slisten);WSACleanup();return -1;}sprintf(sendbuf,"echo:%s",buff);printf("%s\n",sendbuf);slen = (unsigned int)strlen(sendbuf);slen = htonl(slen);ret = send(sServer,(char*)&slen,sizeof(unsigned int),0);if (SOCKET_ERROR == ret){int nErrCode = WSAGetLastError();//错误代码if (WSAENOTCONN == nErrCode){printf("The socket is not connected!\n");}else if(WSAESHUTDOWN == nErrCode){printf("The socket has been shut down!\n");}else if (WSAETIMEDOUT == nErrCode){printf("The connection has been dropped!\n");}else{}closesocket(sServer);closesocket(slisten);WSACleanup();return -1;}ret = send(sServer,sendbuf,strlen(sendbuf),0);if (SOCKET_ERROR == ret){int nErrCode = WSAGetLastError();//错误代码if (WSAENOTCONN == nErrCode){printf("The socket is not connected!\n");}else if(WSAESHUTDOWN == nErrCode){printf("The socket has been shut down!\n");}else if (WSAETIMEDOUT == nErrCode){printf("The connection has been dropped!\n");}else{}closesocket(sServer);closesocket(slisten);WSACleanup();return -1;}}closesocket(sServer);closesocket(slisten);WSACleanup();return 0;}//指定长度接收int recvn(SOCKET s, char * recvbuf, unsigned int fixedlen){int iResult;    //存储单次recv操作的返回值int cnt;         //用于统计相对于固定长度,剩余多少字节尚未接收cnt = fixedlen;while ( cnt > 0 ) {iResult = recv(s, recvbuf, cnt, 0);if ( iResult < 0 ){//数据接收出现错误,返回失败printf("接收发生错误: %d\n", WSAGetLastError());return -1;}if ( iResult == 0 ){//对方关闭连接,返回已接收到的小于fixedlen的字节数printf("连接关闭\n");return fixedlen - cnt;}//printf("接收到的字节数: %d\n", iResult);//接收缓存指针向后移动recvbuf +=iResult;//更新cnt值cnt -=iResult;         }return fixedlen;}int recvvl(SOCKET s, char * recvbuf, unsigned int recvbuflen){int iResult;//存储单次recvn操作的返回值unsigned int reclen; //用于存储报文头部存储的长度信息//获取接收报文长度信息iResult = recvn(s, ( char * )&reclen, sizeof( unsigned int ));if ( iResult !=sizeof ( unsigned int ) ){//如果长度字段在接收时没有返回一个整型数据就返回(连接关闭)或-1(发生错误)if ( iResult == -1 ) {printf("接收发生错误: %d\n", WSAGetLastError());return -1;}else {printf("连接关闭\n");return 0;}}//转换网络字节顺序到主机字节顺序reclen = ntohl( reclen );if ( reclen > recvbuflen ){printf("reclen>recvbuflen: %d>%d\n",reclen,recvbuflen);//如果recvbuf没有足够的空间存储变长消息,则接收该消息并丢弃,返回错误while ( reclen > 0){iResult = recvn( s, recvbuf, recvbuflen );if ( iResult != recvbuflen ) {//如果变长消息在接收时没有返回足够的数据就返回(连接关闭)或-1(发生错误)if ( iResult == -1 ) {printf("接收发生错误: %d\n", WSAGetLastError());return -1;}else {printf("连接关闭\n");return 0;}}reclen -= recvbuflen;//处理最后一段数据长度if ( reclen < recvbuflen )recvbuflen = reclen;}printf("可变长度的消息超出预分配的接收缓存\r\n");return -1;}//接收可变长消息iResult = recvn( s, recvbuf, reclen );if ( iResult != reclen ){//如果消息在接收时没有返回足够的数据就返回(连接关闭)或-1(发生错误)if ( iResult == -1 ) {printf("接收发生错误: %d\n", WSAGetLastError());return -1;}else {printf("连接关闭\n");return 0;}}return iResult;}


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 高中后出国留学档案怎么办 爱迪花园拆了怎么办 燕郊房子卖了户口怎么办 强制险单子丢了怎么办 车辆保险贴丢了怎么办 车险原单子丢了怎么办 车险保单丢了该怎么办? 审车保险单丢了怎么办 湖州公积金贷款买房具体信用怎么办 驾驶本扣分满了怎么办 摩托车被扣12分怎么办 驾照被扣12分怎么办 骑摩托被扣12分怎么办 摩托车没有驾照违章被扣分怎么办 高考登录密码丢了怎么办 高中档案遗失里面体检表怎么办 驾校不给补科一成绩单怎么办 外地驾照转广州体检表怎么办 驾照体检表签名签错怎么办 改完名字后护照怎么办 办健康证没有身份证怎么办 身份证掉了怎么办健康证 华师附小不搬了怎么办 健康证快到期了怎么办 老公想去日本打工怎么办 学生没有资产证明怎么办日本签证 在读证明学校不按模版怎么办 办日本签证没有户口本怎么办 日本大学留级续签失败怎么办 法国签证递交时间太晚怎么办 日本留学生签证更新拒签怎么办 永驻拒签了我该怎么办 越南签证拒签了怎么办 l1签证续签被拒怎么办 去日本跟团签证怎么办 手表里指针掉了怎么办 北京居住证过期半年了怎么办 居住证明居委会不盖章怎么办 小孩感冒鼻子不通气怎么办 1岁宝宝喉咙痰多怎么办 两个月喉咙有痰怎么办