【网络通信】TCP网络编程

2023-11-20

一、面向连接的TCP流模式

在这里插入图片描述

二、server程序

#include <sys/types.h> 
#include <sys/socket.h>
#include <stdio.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <signal.h>

/* socket
 * bind
 * listen
 * accept
 * send/recv
 */

#define SERVER_PORT 8888  // Server端口
#define BACKLOG 	10    // listen请求排队的最大长度

int main(int argc, char **argv)
{
	int iSocketServer;
	int iSocketClient;
	struct sockaddr_in tSocketServerAddr;
	struct sockaddr_in tSocketClientAddr;
	int iRet;
	int iAddrLen;
	int iRecvLen;
	int iClientNum = -1;
	unsigned char ucRecvBuf[1000];

	signal(SIGCHLD,SIG_IGN);  // 避免僵死子进程
	
	/* 1.创建Server端套接字,AF_INET表明地址族 IPv4 Internet,SOCK_DGRAM表明使用 UDP 协议,返回文件描述符。 */
	iSocketServer = socket(AF_INET, SOCK_STREAM, 0);
	if(-1 == iSocketServer)
	{
		printf("socket error!\n");
		return -1;
	}

	tSocketServerAddr.sin_family = AF_INET;           // 地址族 IPv4 Internet
	tSocketServerAddr.sin_port = htons(SERVER_PORT);  // 主机字节序转换为网络字节序 host to net, short
	tSocketServerAddr.sin_addr.s_addr = INADDR_ANY;   // 所有地址 0.0.0.0
	memset(tSocketServerAddr.sin_zero, 0, 8);         // 清零,不使用
	
	/* 2.通过文件描述符绑定Server端套接字的IP地址和端口。 */
	iRet = bind(iSocketServer, (const struct sockaddr *)&tSocketServerAddr, sizeof(struct sockaddr));
	{

		if(-1 == iRet)
		{
			printf("bind error!\n");
			return -1;
		}
	}

	/* 3.创建监听队列,并将 bind 的文件描述符变为监听套接字。 */
	iRet = listen(iSocketServer, BACKLOG);
	if(-1 == iRet)
	{
		printf("listen error!\n");
		return -1;
	}

	while(1)
	{
		iAddrLen = sizeof(struct sockaddr);
		
		/* 4.获得连接请求,并且建立连接。每处理一个连接,则 accept 返回该连接对应的套接字描述符。如果该队列为空,则 accept 阻塞。 */
		iSocketClient = accept(iSocketServer, (struct sockaddr *)&tSocketClientAddr, &iAddrLen);
		if(-1 != iSocketClient)
		{
			// inet_ntoa 将网络地址转换成“.”点隔的字符串格式
			printf("Get Connect From Client %d : %s\n", ++iClientNum, inet_ntoa(tSocketClientAddr.sin_addr));
			
			if(!fork())  // 创建子进程
			{
				while(1)

				{
					/* 5.recv接收 TCP 连接的对端发送来的数据,返回值是实际读到的字节数。 */
					iRecvLen = recv(iSocketClient, ucRecvBuf, 999, 0);
					if(iRecvLen <= 0)
					{
						close(iSocketClient);
						return -1;
					}
					else
					{
						// 数组结尾加'\0'转换为字符数组
						ucRecvBuf[iRecvLen] = '\0';
						printf("Get Msg From Client %d : %s\n", iClientNum, ucRecvBuf);
					}
				}
			}
		}
	}

	close(iSocketServer);
	return 0;
}

三、client程序

#include <sys/types.h> 
#include <sys/socket.h>
#include <stdio.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>

/* socket
 * connect
 * send/recv
 */

#define SERVER_PORT 8888  //Server端口

int main(int argc, char **argv)
{
	int iSocketClient;
	struct sockaddr_in tSocketServerAddr;
	int iRet;
	unsigned char ucSendBuf[1000];
	int iSendLen;

	if(argc != 2)
	{
		printf("Usage: %s <server_ip>\n", argv[0]);
		return -1;
	}
	
	/* 1.创建Client端套接字,AF_INET表明地址族 IPv4 Internet,SOCK_STREAM表明使用 TCP 协议,返回文件描述符。 */
	iSocketClient = socket(AF_INET, SOCK_STREAM, 0);

	tSocketServerAddr.sin_family = AF_INET;           // 地址族 IPv4 Internet
	tSocketServerAddr.sin_port = htons(SERVER_PORT);  // 主机字节序转换为网络字节序 host to net, short
 	//tSocketServerAddr.sin_addr.s_addr = INADDR_ANY; // 所有地址 0.0.0.0
 	if (0 == inet_aton(argv[1], &tSocketServerAddr.sin_addr))
 	{
		printf("invalid server_ip!\n");
		return -1;
	}
	memset(tSocketServerAddr.sin_zero, 0, 8);         // 清零,不使用

	/* 2.connect一般由客户端程序执行,需要指定连接的服务器端的 IP 地址和端口。该方法执行后,会进行三次握手,建立连接。 */
	iRet = connect(iSocketClient, (const struct sockaddr *)&tSocketServerAddr, sizeof(struct sockaddr));
	if(-1 == iRet)
	{
		printf("connect error!\n");
		return -1;
	}

	while(1)
	{
		if(fgets(ucSendBuf, 999, stdin))
		{
			/* 3.send用来向 TCP/UDP 连接的对端发送数据。 */
			iSendLen = send(iSocketClient, ucSendBuf, strlen(ucSendBuf), 0);
			if(iSendLen <= 0)
			{
				close(iSocketClient);
				return -1;
			}
		}
	}
	
	return 0;
}

四、相关文章

1.TCP网络编程

2.sockaddr和sockaddr_in详解

3.socket编程为什么需要htons(), ntohl(), ntohs(),htons() 函数

4.详解linux中的backlog

5.Linux中fork()函数详解

6.memset的用法详解

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【网络通信】TCP网络编程 的相关文章

  • 定义新的套接字选项以在 TCP 内核代码中使用

    我正在尝试向 TCP 内核代码添加一些功能 在tcp input c 我希望我实现的代码仅在某些情况下运行 我想添加一个控制标志 可以从用户空间应用程序设置它 我 认为我 需要添加一个新的套接字选项 以便我可以完成以下操作setsockop
  • TCP recvfrom() 不存储“from”

    我正在使用 TCP 制作一个服务器程序 我想获取我刚刚收到的消息发送者的 IP 地址 这是我的代码 case FD READ Incoming data get ready to receive char buffer DEFAULT BU
  • 如何通过 GPRS 向 GPS 追踪器(TK103、GT02、GT06、TK102 等)发送命令

    这已经被问过这里https stackoverflow com questions 25460743 gps tracker tk103 how to send message through server https stackoverf
  • TCPServer 具有同时全双工通信

    我正在尝试编写一个 C 服务器 客户端 它将同时通过 TCP 相互发送字节数组 我正在努力思考如何实现这一目标 我见过的所有示例都等待消息 然后发送响应 我需要同时进行沟通 我是否需要为服务器和客户端上的传入和传出创建 2 个单独的 TCP
  • TCP 服务器的 GCP 计算引擎防火墙规则

    我创建了一个具有静态外部 IP 地址的 GCP 计算引擎实例 机器类型 n1 standard 2 2 个 vCPU 7 5 GB 内存 操作系统是Linux Debian 我的目的是在机器上创建一个普通的 Node js TCP 服务器
  • 用 C 处理 TCP 的部分返回

    我一直在读Beej 的网络编程指南 http beej us guide bgnet 获取 TCP 连接的句柄 在其中一个示例中 简单 TCP 流客户端的客户端代码如下所示 if numbytes recv sockfd buf MAXDA
  • 如何将我的 Kivy 客户端连接到服务器(TCP、套接字)

    因此 作为我的项目 2D 多人纸牌游戏 的一部分 我已经弄清楚如何在线托管和运行服务器脚本 我的计划是让两个单独的 kivy 客户端连接到服务器 这只是一个带有命令的脚本 但是我对操作顺序有些困惑 因为我think客户端连接可能与消息循环发
  • 连接被对等方重置:套接字写入错误。我的 Java 代码出了什么问题

    我正在尝试从独立的 java 应用程序创建并维护到主机的 TCP 连接 本地端口和服务器端口相同 8999 连接后 我必须向服务器发送一条消息 lt STX gt username fred password abcd lt ETX gt
  • Nodejs TCP连接客户端端口分配

    我使用nodejs在客户端和服务器之间创建了tcp连接 网络模块 https nodejs org api net html 服务器正在侦听已经预定义的端口 并且客户端正在连接到该端口 据我了解客户端的端口是由节点动态分配的 那是对的吗 节
  • 是什么导致 MSSQL 中出现“非阻塞套接字上的操作将阻塞”错误?

    错误 异常查询为 CREATE NONCLUSTERED INDEX I1 ON AllAccounts BAK Master received Day ASC 出现异常 发生一个或多个错误 错误 异常内部异常无法从传输连接读取数据 非阻塞
  • Socket ReceiveAsync 合并数据包

    我打算通过套接字接收数据包 但由于它们是从发送方以高频率发送的 因此其中许多数据包被打包成一个byte array SocketAsyncEventArgs Buffer然后保存多个数据包 即使它们是单独发送的 使用验证wireshark
  • 如何在NodeJS中测试socket.setKeepAlive

    我尝试在NodeJS中测试setKeepAlive 的功能 我在同一本地网络中的不同计算机上运行 Server js 和 client js 然后 我关闭了客户端计算机上的 WiFi 连接 断开互联网连接 15分钟后 仍然没有消息抛出 这是
  • net.TCPConn 允许在 FIN 数据包后写入

    我正在尝试为一些服务器端代码编写单元测试 但我在确定关闭测试用例时遇到了困难 环回 TCP 连接似乎无法正确处理干净关闭 我在一个示例应用程序中重现了这一点 该应用程序按顺序执行以下操作 创建客户端和服务器连接 通过从客户端向服务器成功发送
  • Web 服务器可以处理多少个套接字连接?

    假设我要获得共享 虚拟或专用托管 我在某处读到服务器 计算机一次只能处理 64 000 个 TCP 连接 这是真的吗 无论带宽如何 任何类型的托管可以处理多少个 我假设 HTTP 通过 TCP 工作 这是否意味着只有 64 000 个用户可
  • 构建多线程 TCP/IP 服务器

    我想构建一个可供最多 100 个并发客户端使用的 TCP IP 服务器 但仍不确定如何开始 至少我需要服务器 监听客户端 并将它们全部存储在数组或列表中 对于每个客户端 它需要根据其客户端状态接收和发送数据 当有人连接或断开连接时 服务器应
  • Python套接字模块:Recv()数据响应被切断

    解释 我目前正在尝试使用 python 脚本控制智能电源板 为了实现这一点 我使用了带有套接字模块的 TCP 连接 大约 75 的情况下 我会得到我正在寻找的响应 数据 并且一切都运行良好 然而 大约 25 的情况下 响应会以完全相同的长度
  • 是否可以找到哪个用户位于 localhost TCP 连接的另一端?

    这是一个编程问题 但它是 Linux Unix 特定的 如果我从本地主机获得 TCP 连接 是否有一种简单的方法可以告诉哪个用户在 C 程序内建立了连接而无需 shell 我知道这对于 Unix 域套接字来说并不太难 我已经知道远程 IP
  • 为什么 TCP 段中的 SYN 或 FIN 位会占用序列号空间中​​的一个字节?

    我试图理解这种设计背后的基本原理 我浏览了一些 RFC 但没有发现任何明显的东西 这并不是特别微妙 这样 SYN 和 FIN 位本身就可以被确认 因此如果丢失则可以重新发送 例如 如果连接关闭而没有发送更多数据 那么如果 FIN 没有发送任
  • 为什么我收到的数据包数据大小大于mss?

    我在两台 PC 上使用 ifconfig ethX mtu 300 修改了 MTU 并使用 netperf 测试网络 我用 WireShark 嗅探了 SYN 数据包中的 MSS 260 但我得到了一些大于 260 的数据包 为什么 嗅探器
  • 使用 boost 异步发送和接收自定义数据包?

    我正在尝试使用 boost 异步发送和接收自定义数据包 根据我当前的实现 我有一些问题 tcpclient cpp include tcpclient h include

随机推荐

  • VS2017+WDK10驱动编译与调试

    驱动编译 安装VS2017 和WDK 10 下载地址 https docs microsoft com zh cn windows hardware drivers download the wdk 如果安装VS2017时没有选择安装win
  • 三面美团被问:MySQL的B+Tree索引到底是咋回事?聚簇索引到底是如何长高的?这不是必过?

    你肯定知道MySQL进行CRUD是在内存中进行的 也就是在Buffer Pool中 然后你也知道了当内存中没有MySQL需要的数据时 MySQL会从Disk中通过IO操作将数据读入内存中 读取的单位呢就是 数据页 一般数据页长下面这样 没错
  • 17.清晰架构(01): 融合 DDD、洋葱架构、整洁架构、CQRS...(译)

    17 清晰架构 01 融合 DDD 洋葱架构 整洁架构 CQRS 译 原文 https herbertograca com 2017 11 16 explicit architecture 01 ddd hexagonal onion cl
  • 作物产量常用的单位换算公式

    作物产量常用的单位换算公式 一 产量的定义 Agronomic Yields 1 Abstrct 2 Protocol 2 1 Grain Harvest of Annual Row crops 标准含水量 For corn the sta
  • Python人工智能,13天快速入门机器学习教程,含14大案例(NBA球员数据分析,北京租房数据,疾病数据预测等)

    40h小时入门人工智能 带你了解人工智能的前世今生 带你掌握人工智能经典算法 可掌握核心能力 1 掌握机器学习中处理数据的方法 2 理解经典的机器学习算法原理 3 掌握机器学习中工作的具体流程 Python人工智能13天快速入门机器学习教程
  • Android studio Mac快捷键连续选择相同内容和选中当前光标位置内容

    刚从Windows换到Mac第一件事绝对是先熟悉AS的快捷键 有两个很好用的快捷键找了很久都没找到 这里放出来 连续选择相同内容 Windows Alt j Control G Mac接Windows键盘是 Ctrl G 效果如下 选中当前
  • 面试之MySQL调优问题

    文章目录 前言 一 MySQL的底层原理粗解 1 1 MySQL的底层运作 1 2 MySQL的存储方式 二 索引 重点内容 2 1 索引是什么 2 2 MySQL调优到底是调啥的 2 3 如何创建一个索引 2 3 1在创建表的时候创建索引
  • Linux 上传删除文件命令

    rm 文件名 删除 rz Enter 上传文件 Ctrl z 退出
  • 枚举基础问题

    枚举问题 与7无关的数为例 枚举问题 这类问题并不复杂 对于题目本身只需要通过循环去遍历 列举出所有可能满足条件的情况 一个一个罗列出来 称为枚举问题 例如下面的题目 与7无关的数 这就是一类枚举问题 将所有可能满足 与7无关的数 罗列出来
  • POC - Adobe ColdFusion 反序列化漏洞(CVE-2017-3066)

    安装010Editer 下载链接 http www pc6 com softview SoftView 55129 html 复制POC的十六进制 00 03 00 00 00 01 00 00 00 00 00 00 00 01 11 0
  • html制作简单的表单<form>

    文章目录 一 使用到的标签用法介绍 1 演示标签代码 2 标签使用具体介绍 二 表单制作代码 三 结果显示 一 使用到的标签用法介绍 1 演示标签代码
  • 输出九九乘法表

    九九乘法表 尝试编写程序 输出九九乘法表 具体如下图所示 代码 include
  • redis服务器信息统计,Redis 返回关于 Redis 服务器的各种信息和统计数值 命令:INFO...

    INFO section 以一种易于解释 parse 且易于阅读的格式 返回关于 Redis 服务器的各种信息和统计数值 通过给定可选的参数 section 可以让命令只返回某一部分的信息 server 一般 Redis 服务器信息 包含以
  • 突发!ITELLYOU要改版了!

    微信公众号 网管小贾 个人博客 www sysadm cc 经常下载Windows系统镜像的老司机中 我敢保证十之八九对 MSDN 我告诉你 这个网站再熟悉不过 可是对于新手小白们来说 这个站TA究竟是个啥 其实 MSDN 我告诉你 是个名
  • 解决火狐首次启动太慢的方法

    众所周知 火狐浏览器有一定的优越性 现在众多的网站都采用了jquery技术 而ie在加载jquery上效果实在太差 尤其是配置稍低的情况下 ie很容易被卡死 这就体现出了火狐的优势 但火狐唯一不足的就是第一次启动的速度非常的慢 下面就是解决
  • 世界芯中国芯RISC-V相关资源及进展

    目录 1 RISC V介绍 RISC V为何会在最近两年迅速崛起 RISC V处理器生态 RISC V商业模式 2 RISC V发展历程 3 RISC V国际协会 4 中国RISC V产业联盟 5 RISC V相关资源 1 指令集规范 2
  • kotlin 之于 java 的差异

    一 变量声名 赋值和访问 kotlin 变量是空安全的 一般要求声明时就赋值 声名变量有两个关键字var和val 其中val相当于 java 的中的final 变量类型可显式给出 也可隐式推断 变量也可分可空类型和非空类型 以下给出几种声名
  • ROS1 ROS2学习

    ROS1 ROS2学习 安装 ROS ROS1 ROS2 命令行界面 ROS2 功能包相关指令 ROS 命令行工具 ROS1 CLI工具 ROS2 CLI工具 ROS 通信核心概念 节点 Node 节点相关的CLI 话题 Topic 编写发
  • Altium Designer 20 常见错误

    记录学习过程中出现的错误及解决方法 1 off grid pin问题和Off grid Net Label问题 Off grid Net Label问题解决 只需要选中出现警告的元件 然后按A再按G即可 或者按Shift Ctrl D也行
  • 【网络通信】TCP网络编程

    TCP网络编程 一 面向连接的TCP流模式 二 server程序 三 client程序 四 相关文章 1 TCP网络编程 2 sockaddr和sockaddr in详解 3 socket编程为什么需要htons ntohl ntohs h