TCP中send和recv函数针对的是字符(无边界), 而不是字符串(以‘\0‘作为边界)

2024-02-06 14:58

本文主要是介绍TCP中send和recv函数针对的是字符(无边界), 而不是字符串(以‘\0‘作为边界),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

         我第一次玩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); // 发送数据到客户端,最后一个参数一般设置为0while(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, 10int 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函数对所传的内容不敏感, 它关注的是字符, 仅此而已。

 

这篇关于TCP中send和recv函数针对的是字符(无边界), 而不是字符串(以‘\0‘作为边界)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/684669

相关文章

hdu1171(母函数或多重背包)

题意:把物品分成两份,使得价值最接近 可以用背包,或者是母函数来解,母函数(1 + x^v+x^2v+.....+x^num*v)(1 + x^v+x^2v+.....+x^num*v)(1 + x^v+x^2v+.....+x^num*v) 其中指数为价值,每一项的数目为(该物品数+1)个 代码如下: #include<iostream>#include<algorithm>

C++操作符重载实例(独立函数)

C++操作符重载实例,我们把坐标值CVector的加法进行重载,计算c3=c1+c2时,也就是计算x3=x1+x2,y3=y1+y2,今天我们以独立函数的方式重载操作符+(加号),以下是C++代码: c1802.cpp源代码: D:\YcjWork\CppTour>vim c1802.cpp #include <iostream>using namespace std;/*** 以独立函数

函数式编程思想

我们经常会用到各种各样的编程思想,例如面向过程、面向对象。不过笔者在该博客简单介绍一下函数式编程思想. 如果对函数式编程思想进行概括,就是f(x) = na(x) , y=uf(x)…至于其他的编程思想,可能是y=a(x)+b(x)+c(x)…,也有可能是y=f(x)=f(x)/a + f(x)/b+f(x)/c… 面向过程的指令式编程 面向过程,简单理解就是y=a(x)+b(x)+c(x)

每日一题|牛客竞赛|四舍五入|字符串+贪心+模拟

每日一题|四舍五入 四舍五入 心有猛虎,细嗅蔷薇。你好朋友,这里是锅巴的C\C++学习笔记,常言道,不积跬步无以至千里,希望有朝一日我们积累的滴水可以击穿顽石。 四舍五入 题目: 牛牛发明了一种新的四舍五入应用于整数,对个位四舍五入,规则如下 12345->12350 12399->12400 输入描述: 输入一个整数n(0<=n<=109 ) 输出描述: 输出一个整数

【Go】go连接clickhouse使用TCP协议

离开你是傻是对是错 是看破是软弱 这结果是爱是恨或者是什么 如果是种解脱 怎么会还有眷恋在我心窝 那么爱你为什么                      🎵 黄品源/莫文蔚《那么爱你为什么》 package mainimport ("context""fmt""log""time""github.com/ClickHouse/clickhouse-go/v2")func main(

利用matlab bar函数绘制较为复杂的柱状图,并在图中进行适当标注

示例代码和结果如下:小疑问:如何自动选择合适的坐标位置对柱状图的数值大小进行标注?😂 clear; close all;x = 1:3;aa=[28.6321521955954 26.2453660695847 21.69102348512086.93747104431360 6.25442246899816 3.342835958564245.51365061796319 4.87

OpenCV结构分析与形状描述符(11)椭圆拟合函数fitEllipse()的使用

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C++11 算法描述 围绕一组2D点拟合一个椭圆。 该函数计算出一个椭圆,该椭圆在最小二乘意义上最好地拟合一组2D点。它返回一个内切椭圆的旋转矩形。使用了由[90]描述的第一个算法。开发者应该注意,由于数据点靠近包含的 Mat 元素的边界,返回的椭圆/旋转矩形数据

2024.9.8 TCP/IP协议学习笔记

1.所谓的层就是数据交换的深度,电脑点对点就是单层,物理层,加上集线器还是物理层,加上交换机就变成链路层了,有地址表,路由器就到了第三层网络层,每个端口都有一个mac地址 2.A 给 C 发数据包,怎么知道是否要通过路由器转发呢?答案:子网 3.将源 IP 与目的 IP 分别同这个子网掩码进行与运算****,相等则是在一个子网,不相等就是在不同子网 4.A 如何知道,哪个设备是路由器?答案:在 A

Unity3D 运动之Move函数和translate

CharacterController.Move 移动 function Move (motion : Vector3) : CollisionFlags Description描述 A more complex move function taking absolute movement deltas. 一个更加复杂的运动函数,每次都绝对运动。 Attempts to

图解TCP三次握手|深度解析|为什么是三次

写在前面 这篇文章我们来讲解析 TCP三次握手。 TCP 报文段 传输控制块TCB:存储了每一个连接中的一些重要信息。比如TCP连接表,指向发送和接收缓冲的指针,指向重传队列的指针,当前的发送和接收序列等等。 我们再来看一下TCP报文段的组成结构 TCP 三次握手 过程 假设有一台客户端,B有一台服务器。最初两端的TCP进程都是处于CLOSED关闭状态,客户端A打开链接,服务器端