我第一次玩TCP的时候, 接触的都是字符串的传输。 后来,我接触了字符的传输, 才意识到, 原来,TCP中send和recv函数针对的是字符(无边界), 而不是字符串(以'\0'作为边界)。
先看服务端程序:
#include <stdio.h> #include <winsock2.h> // winsock接口 #pragma comment(lib, "ws2_32.lib") // winsock实现 int main() { WORD wVersionRequested; // 双字节,winsock库的版本 WSADATA wsaData; // winsock库版本的相关信息 wVersionRequested = MAKEWORD(1, 1); // 0x0101 即:257 // 加载winsock库并确定winsock版本,系统会把数据填入wsaData中 WSAStartup( wVersionRequested, &wsaData ); // AF_INET 表示采用TCP/IP协议族 // SOCK_STREAM 表示采用TCP协议 // 0是通常的默认情况 unsigned int sockSrv = socket(AF_INET, SOCK_STREAM, 0); SOCKADDR_IN addrSrv; addrSrv.sin_family = AF_INET; // TCP/IP协议族 addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); // socket对应的IP地址 addrSrv.sin_port = htons(8888); // socket对应的端口 // 将socket绑定到某个IP和端口(IP标识主机,端口标识通信进程) bind(sockSrv,(SOCKADDR*)&addrSrv, sizeof(SOCKADDR)); // 将socket设置为监听模式,5表示等待连接队列的最大长度 listen(sockSrv, 5); SOCKADDR_IN addrClient; int len = sizeof(SOCKADDR); while(1) { // sockSrv为监听状态下的socket // &addrClient是缓冲区地址,保存了客户端的IP和端口等信息 // len是包含地址信息的长度 // 如果客户端没有启动,那么程序一直停留在该函数处 unsigned int sockConn = accept(sockSrv,(SOCKADDR*)&addrClient, &len); char sendBuf[100] = {'1', '2', '3', '4', '5', '\0', '6', '7', '8', '9', '\0'}; send(sockConn, sendBuf, 10, 0); // 发送数据到客户端,最后一个参数一般设置为0 while(1); } closesocket(sockSrv); WSACleanup(); return 0; }启动它。
然后看客户端程序:
#include <winsock2.h> #include <stdio.h> #pragma comment(lib, "ws2_32.lib") int main() { WORD wVersionRequested; WSADATA wsaData; wVersionRequested = MAKEWORD(1, 1); WSAStartup( wVersionRequested, &wsaData ); 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_family = AF_INET; addrSrv.sin_port = htons(8888); connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR)); char recvBuf[100] = {0}; int number = recv(sockClient, recvBuf, 10, 0); // 接收10个字符 printf("%s, %d\n", recvBuf, number); // 12345, 10 int i = 0; for(i = 0; i < 10; i++) { printf("%d\n", recvBuf[i] - '0'); } closesocket(sockClient); WSACleanup(); return 0; }程序运行结果为:
12345, 10
1
2
3
4
5
-48
6
7
8
9
可见, 后面的6789也都发过来了, 由此可见, TCP中send和recv函数针对的是字符(无边界), 而不是字符串(以'\0'作为边界)。 换句话说, tcp的send和recv函数对所传的内容不敏感, 它关注的是字符, 仅此而已。