vc++socket笔记3-4
判断数据是否接收完,有根据双方约定好的长度判断,根据结束符判断,在文件头给定长度判断
服务器端(serve):
#define _WINSOCK_DEPRECATED_NO_WARNINGS #include<WinSock2.h> #include<strsafe.h> #pragma comment(lib,"Ws2_32.lib") #define BUF_LEN 300 using namespace std; int main() { WORD wVersionRequested; WSADATA wsaData; int err, iRes,i;// 错误码 wVersionRequested = MAKEWORD(2, 2);// 版本号 err = WSAStartup(wVersionRequested, &wsaData); if (err != 0)return 0; if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)// 如果版本号低8位不为2或高8位不为2则版本号错误,不知道有什么意义 { WSACleanup(); return 0; } SOCKET sockSrv = socket(AF_INET, SOCK_STREAM, 0); SOCKADDR_IN addrSrv; addrSrv.sin_addr.S_un.S_addr = htonl(ADDR_ANY); // addrSrv.sin_addr.S_un.S_addr = inet_addr("192.168.1.2"); addrSrv.sin_family = AF_INET; addrSrv.sin_port = htons(11451); bind(sockSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR)); listen(sockSrv, 5); SOCKADDR_IN addrClient; int len = sizeof(SOCKADDR); int cn = 0; while (1) { printf("----------等待客户端------------\n"); SOCKET sockConn = accept(sockSrv, (SOCKADDR*)&addrClient, &len); char sendBuf[111]; for (cn = 0;cn < 50;i++) { memset(sendBuf, 'a', 111); if (cn == 49) sendBuf[110] = 'b'; send(sockConn, sendBuf, 111, 0); } char recBuf[BUF_LEN]; do { iRes = recv(sockConn, recBuf, BUF_LEN, 0); if (iRes > 0) { printf("\nRecv %d bytes:", iRes); for (int i = 0;i < iRes;i++)printf("%c", recBuf[i]); printf("\n"); } else if (iRes == 0)printf("\n客户端关闭连接\n"); else { printf("recv failed with error:%d\n", WSAGetLastError()); closesocket(sockConn); WSACleanup(); return 1; } } while (iRes > 0); closesocket(sockConn); puts("是否继续监听(y/n)"); char ch[2]; scanf_s("%s", ch, 2); if (ch[0] != 'y')break; } closesocket(sockSrv); WSACleanup(); return 0; }
客户端(client):
#define _WINSOCK_DEPRECATED_NO_WARNINGS #include<WinSock2.h> #include<strsafe.h> #pragma comment(lib,"Ws2_32.lib") #define BUF_LEN 300 using namespace std; int main() { WORD wVersionRequested; WSADATA wsaData; int err;// 错误码 u_long argp; char szMsg[] = "你好服务器,我已经收到你的信息"; wVersionRequested = MAKEWORD(2, 2);// 版本号 err = WSAStartup(wVersionRequested, &wsaData); if (err != 0)return 0; if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)// 如果版本号低8位不为2或高8位不为2则版本号错误,不知道有什么意义 { WSACleanup(); return 0; } SOCKET sockClient = socket(AF_INET, SOCK_STREAM, 0); SOCKADDR_IN addrSrv; addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); // addrSrv.sin_addr.S_un.S_addr = inet_addr("192.168.1.2"); addrSrv.sin_family = AF_INET; addrSrv.sin_port = htons(11451); err = connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR)); if (SOCKET_ERROR == err) { printf("连接服务器失败\n"); return 0; } char recvBuf[BUF_LEN]; int i, cn = 1, iRes; int leftlen = 50 * 111; while (leftlen > 0) { iRes = recv(sockClient, recvBuf, BUF_LEN, 0); if (iRes > 0) { printf("\nNO.%d Recv %d bytes:", cn++, iRes); for (i = 0;i < iRes;i++) printf("%c", recvBuf[i]); printf("\n"); } else if (iRes == 0)puts("\n服务器端关闭发送连接\n"); else { printf("recv failed:%d\n", WSAGetLastError()); printf("recv failed with error:%d\n", WSAGetLastError()); closesocket(sockClient); WSACleanup(); return 1; } leftlen = leftlen - iRes; } char sendBuf[100]; sprintf_s(sendBuf, "我是客户端,我已经完成数据接受了\0"); send(sockClient, sendBuf, sizeof(sendBuf) + 1, 0); memset(sendBuf, 0, sizeof(sendBuf)); puts("向服务器端发送数据完成"); closesocket(sockClient); system("pause");// 卡屏 WSACleanup(); return 0; }


服务器端(serve):
#define _WINSOCK_DEPRECATED_NO_WARNINGS #include<WinSock2.h> #include<strsafe.h> #pragma comment(lib,"Ws2_32.lib") #define BUF_LEN 300 using namespace std; struct MyData { int nLen; char data[0]; }; int main() { WORD wVersionRequested; WSADATA wsaData; int err, iRes,i;// 错误码 wVersionRequested = MAKEWORD(2, 2);// 版本号 err = WSAStartup(wVersionRequested, &wsaData); if (err != 0)return 0; if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)// 如果版本号低8位不为2或高8位不为2则版本号错误,不知道有什么意义 { WSACleanup(); return 0; } SOCKET sockSrv = socket(AF_INET, SOCK_STREAM, 0); SOCKADDR_IN addrSrv; addrSrv.sin_addr.S_un.S_addr = htonl(ADDR_ANY); // addrSrv.sin_addr.S_un.S_addr = inet_addr("192.168.1.2"); addrSrv.sin_family = AF_INET; addrSrv.sin_port = htons(11451); bind(sockSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR)); listen(sockSrv, 5); SOCKADDR_IN addrClient; int len = sizeof(SOCKADDR); int cn = 0; struct MyData* mydata; while (1) { printf("----------等待客户端------------\n"); SOCKET sockConn = accept(sockSrv, (SOCKADDR*)&addrClient, &len); cn = 5550; { mydata = (MyData*)malloc(sizeof(MyData) + cn); mydata->nLen = htonl(cn); memset(mydata->data, 'a', cn); mydata->data[cn - 1] = 'b'; send(sockConn, (char*)mydata, sizeof(MyData) + cn, 0); free(mydata); } char recBuf[BUF_LEN]; do { iRes = recv(sockConn, recBuf, BUF_LEN, 0); if (iRes > 0) { printf("\nRecv %d bytes:", iRes); for (int i = 0;i < iRes;i++)printf("%c", recBuf[i]); printf("\n"); } else if (iRes == 0)printf("\n客户端关闭连接\n"); else { printf("recv failed with error:%d\n", WSAGetLastError()); closesocket(sockConn); WSACleanup(); return 1; } } while (iRes > 0); closesocket(sockConn); puts("是否继续监听(y/n)"); char ch[2]; scanf_s("%s", ch, 2); if (ch[0] != 'y')break; } closesocket(sockSrv); WSACleanup(); return 0; }
客户端(client):
#define _WINSOCK_DEPRECATED_NO_WARNINGS #include<WinSock2.h> #include<strsafe.h> #pragma comment(lib,"Ws2_32.lib") #define BUF_LEN 300 using namespace std; int main() { WORD wVersionRequested; WSADATA wsaData; int err;// 错误码 u_long argp; char szMsg[] = "你好服务器,我已经收到你的信息"; wVersionRequested = MAKEWORD(2, 2);// 版本号 err = WSAStartup(wVersionRequested, &wsaData); if (err != 0)return 0; if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)// 如果版本号低8位不为2或高8位不为2则版本号错误,不知道有什么意义 { WSACleanup(); return 0; } SOCKET sockClient = socket(AF_INET, SOCK_STREAM, 0); SOCKADDR_IN addrSrv; addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); // addrSrv.sin_addr.S_un.S_addr = inet_addr("192.168.1.2"); addrSrv.sin_family = AF_INET; addrSrv.sin_port = htons(11451); err = connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR)); if (SOCKET_ERROR == err) { printf("连接服务器失败\n"); return 0; } char recvBuf[BUF_LEN]; int i, cn = 1, iRes; int leftlen;// = 50 * 111; unsigned char* pdata; iRes = recv(sockClient, (char*)&leftlen, sizeof(int),0); leftlen = ntohl(leftlen); while (leftlen > 0) { iRes = recv(sockClient, recvBuf, BUF_LEN, 0); if (iRes > 0) { printf("\nNO.%d Recv %d bytes:", cn++, iRes); for (i = 0;i < iRes;i++) printf("%c", recvBuf[i]); printf("\n"); } else if (iRes == 0)puts("\n服务器端关闭发送连接\n"); else { printf("recv failed:%d\n", WSAGetLastError()); printf("recv failed with error:%d\n", WSAGetLastError()); closesocket(sockClient); WSACleanup(); return 1; } leftlen = leftlen - iRes; } char sendBuf[100]; sprintf_s(sendBuf, "我是客户端,我已经完成数据接受了\0"); send(sockClient, sendBuf, sizeof(sendBuf) + 1, 0); memset(sendBuf, 0, sizeof(sendBuf)); puts("向服务器端发送数据完成"); closesocket(sockClient); system("pause");// 卡屏 WSACleanup(); return 0; }
注意传送整型数据时要将数据转为大端存储,也就是网络字节序,这是个良好的习惯。而且本机或局域网下这么做貌似能得到正确的结果,但是路由器网络环境上好像有问题。
效果如上图,懒得截。
浙公网安备 33010602011771号