C语言模拟TCP通信-------收发数据

2023-05-16

 简介

这篇是我学习网络编程时初次接触到的,感觉挺适合初学者,下文主要介绍了如何使用Linux模拟TCP通信,分为客户端和服务器端两大部分,外加一个总的头文件

 流程

 服务器端和客户端使用TCP的流程如下所示

 

 所用函数

 (1) socket():该函数用于创建一个套接字,同时指定协议和类型。
 (2) bind():该函数将保存在相应地址结构中的地址信息与套接字进行绑定,它主要用于服务器端,客户端创建的套接字可以不绑定定地址。
(3)listen():在服务器端程序成功建立套接字并与地址进行绑定之后通过调用listen()函数将套接字设置成监听模式(被动模式),准备接收客户端的连接请求。
(4)accept():服务器端通过调用accept()函数等待并接收客户端的连接请求。建立好 TCP 连接后,该函数会返回一个新的已连接套接字。

(5)connect():客户端通过该函数向服务器端的监听套接字发送连接请求。
(6)send()和recv():这两个函数通常在 TCP 通信过程中用于发送和接收数据,也可以用在 UDP 中。
(7)sendto()和 recvfrom():这两个函数一般在 UDP 通信过程中用于发送和接收数据。当用在 TCP 时,后面的几个与地址有关的参数不起作用,函数作用等同于 send ()和recv()。

 头文件

#ifndef _NET_H
#define _NET_H

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

#endif

 客户端

步骤

     创建发送端Socket对象(创建连接)
     获取输出流对象
     发送数据
     释放资源

#include "net.h"

int tcp_connect(const char *ip,int port);
int tcp_connect(const char *ip,int port)
{
	//1,创建socket对象,流式套接字
	//参数1 地址族 AF_INET表示IPV4协议
	//参数2 套接字类型 SOCK_STREAM表示流式套接字 适用于TCP协议
	//参数3 一般为0
	int tcp_socket=socket(AF_INET,SOCK_STREAM,0);
	if(tcp_socket<0)
	{
		perror("socket error\n");
		return -1;
	}
	printf("socket ok\n");
	//2.设置对方的IP地址和端口号
	//2.1定义一个结构体,赋值
	struct sockaddr_in server;

	server.sin_family=AF_INET;//IPV4
	server.sin_port=htons(port);//端口号
	server.sin_addr.s_addr=inet_addr(ip);//转换成网络字节序
	//3,请求连接
	//参数1 socket 对象
	//参数2 struct socket *    实际struct socksddr_in
	if(connect(tcp_socket,(struct sockaddr *)&server,sizeof(server))<0)
	{
		perror("connect error");
		return -1;
	}
	printf("connect ok\n");
	return tcp_socket;
}

int main(int argc, const char *argv[])
{
	//1,创建socket对象,流氏套接字
	//2.设置对方的IP地址和端口号
	//3,请求连接
	//4.发送接受消息
	//5.关闭socket对象
	if(argc<3)
	{
		printf("输入错误,请重新输入\n");
		exit(1);
	}

	int tcp_socket=tcp_connect(argv[1],atoi(argv[2]));
	char buf[20]={'\0'};
	fgets(buf,sizeof(buf),stdin);
	send(tcp_socket,buf,strlen(buf),0);
	//5关闭socket对象
	close(tcp_socket);
	return 0;
}

 服务器端

步骤:
         创建接收端Socket对象
         监听
         获取输入流对象
         获取数据
         输出数据
         释放资源

#include "net.h"

int tcp_server(const char *ip,int port);
int tcp_server(const char *ip,int port)
{
	//1,创建socket对象,流式套接字
	//参数1 地址族 AF_INET表示IPV4协议
	//参数2 套接字类型 SOCK_STREAM表示流式套接字 适用于TCP协议
	//参数3 一般为0
	int tcp_socket=socket(AF_INET,SOCK_STREAM,0);
	if(tcp_socket<0)
	{
		perror("socket error\n");
		return -1;
	}
	//2.设置对方的IP地址和端口号
	//2.1定义一个结构体,赋值
	struct sockaddr_in server;
	memset(&server,'\0',sizeof(server));
	server.sin_family=AF_INET;//IPV4
	server.sin_port=htons(port);//端口号
	server.sin_addr.s_addr=inet_addr(ip);//转换成网络字节序

	//3,请求连接
	//参数1 socket 对象
	//参数2 struct socket *    实际struct socksddr_in
	if(bind(tcp_socket,(struct sockaddr *)&server,sizeof(server))<0)
	{
		perror("bind error\n");
		return -1;
	}
	printf("bind ok\n");
	if(listen(tcp_socket,5)<0)
	{
		perror("listen error");
	}
	printf("listen ok\n");
	return tcp_socket;
}

int main(int argc, const char *argv[])
{
	//1.socket对象,流氏套接字
	//2.设置对方的IP地址和端口号
	//3.请求连接
	//4.发送接受消息
	//5.关闭socket对象
	if(argc!=3)
	{
		printf("输入错误,请重新输入\n");
		exit(1);
	}

	int tcp_socket=tcp_server(argv[1],atoi(argv[2]));
	int newfd=0;
	struct sockaddr_in client;
	int len=sizeof(client);
	newfd=accept(tcp_socket,(struct sockaddr *)&client,&len);
	if(newfd<0)
	{
		perror("accept error");
		return -1;
	}
	printf("accept ok\n");
	printf("client ip:%s port:%d\n",inet_ntoa(client.sin_addr),ntohs(client.sin_port));

	char buf[20]={'\0'};
	recv(newfd,buf,sizeof(buf),0);
	printf("%s\n",buf);
	//5.关闭socket对象
	close(tcp_socket);
	return 0;
}

小结

以上就是小编边学边码出来的,如有不对,请多指正~~

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

C语言模拟TCP通信-------收发数据 的相关文章

  • TCP 数据偶尔会以错误的顺序接收且不完整

    我用 Java 创建了 TCP 服务器应用程序 并用 C 创建了客户端应用程序 当我发送数据时 客户端有时会乱序接收数据 有时部分会完全丢失 基本上 我在服务器 java 中使用的代码如下 已删除 ServerSocket welcomeS
  • TCP recvfrom() 不存储“from”

    我正在使用 TCP 制作一个服务器程序 我想获取我刚刚收到的消息发送者的 IP 地址 这是我的代码 case FD READ Incoming data get ready to receive char buffer DEFAULT BU
  • WCF TCP 客户端 - 如何使用它们的基本指南?

    我有一个 WCF 服务并希望使用 TCP 绑定连接到它 这一切都很好 但是你应该如何处理客户呢 我注意到 如果您为每个调用创建一个新客户端 它不会重新使用该通道 并会留下一堆 TCP 连接 直到超时 创建客户端 调用其方法 然后关闭它是正常
  • TCPServer 具有同时全双工通信

    我正在尝试编写一个 C 服务器 客户端 它将同时通过 TCP 相互发送字节数组 我正在努力思考如何实现这一目标 我见过的所有示例都等待消息 然后发送响应 我需要同时进行沟通 我是否需要为服务器和客户端上的传入和传出创建 2 个单独的 TCP
  • 连接被对等方重置:套接字写入错误。我的 Java 代码出了什么问题

    我正在尝试从独立的 java 应用程序创建并维护到主机的 TCP 连接 本地端口和服务器端口相同 8999 连接后 我必须向服务器发送一条消息 lt STX gt username fred password abcd lt ETX gt
  • 无法通过 ngrok ssh 进入远程 Linux

    远程Linux计算机位于内部网络中 没有公共IP地址 所以我安装了ngrok ngrok tcp 22 ngrok by inconshreveable Ctrl C 退出 在线隧道状态版本2 0 19 2 0 17网页界面http 127
  • 为什么我无法发送这个IP数据包?

    我正在尝试使用 C 发送 IP 数据包 destAddress IPAddress Parse 192 168 0 198 destPort 80 Create a raw socket to send this packet rawSoc
  • 很难理解带有 async_read 和 async_write 的 Boost ASIO TCP 的一些概念

    我很难理解使用 async read 和 async write 时构建 tcp 客户端的正确方法 这examples http www boost org doc libs 1 38 0 doc html boost asio examp
  • 查找网络中的所有IP地址

    我正在尝试用 C 来做这个 我需要找到我的网络中所有活动的 IP 地址并将它们显示在列表中 我可以 ping 网络中所有可用的 1 255 IP 地址 但我想让这个过程更快 此代码在大约 1 秒内扫描我的网络 255 个 D 级段 我在 V
  • 使用 iPhone 作为热点时 TCP 连接无法正常工作

    我正在开发一个 iOS 应用程序 它通过 TCP 套接字连接到在 Android 上运行的服务器应用程序 为了找到第二个设备的 IP 我使用 UDP 请求并接收服务器的 IP 当我将它们连接到 Wi Fi 网络或使用 Android 设备作
  • 如何模拟客户端和服务器之间的套接字断开连接(在 Windows 上)?

    我已经实现了一种 心跳解决方案 我想看看在实际情况下网络 故障 时会发生什么 特别是当套接字上没有流量时发生这种情况 问题 我只有一台电脑 我在windows java上 我想简单地拔掉网线 停用网卡不会影响这两个进程 因为它们在同一个盒子
  • C# - 从客户端检查 TCP/IP 套接字状态

    我想为我的 TCP IP 客户端类提供 CheckConnection 函数 以便我可以检查是否发生了错误 我自己的客户端断开连接 服务器断开连接 服务器卡住等 我有类似的东西 bool isConnectionActive false i
  • C# Socket.receive连续接收0字节且循环中不阻塞

    我正在尝试用 C 编写一个最简单的多线程 TCP 服务器 它接收来自多个客户端的数据 每次连接新客户端时 都会建立套接字连接 并将套接字作为参数传递给新类函数 之后运行 while 循环并接收数据 直到客户端连接为止 这里的问题是 sock
  • 自动打开命名管道和 tcp\ip

    我正在安装一个需要修改 SQL Server 的新产品 具体来说 启用 tcp ip 并打开命名管道 我知道如何手动完成 我想要的是一种通过 SQL 或 C 代码为新客户自动化执行此操作的方法 我希望有任何关于正确方向的建议 您可以使用 C
  • 是否可以找到哪个用户位于 localhost TCP 连接的另一端?

    这是一个编程问题 但它是 Linux Unix 特定的 如果我从本地主机获得 TCP 连接 是否有一种简单的方法可以告诉哪个用户在 C 程序内建立了连接而无需 shell 我知道这对于 Unix 域套接字来说并不太难 我已经知道远程 IP
  • 简单的跨平台 TCP IP API?

    我不打算使用像 QT 或 wxWidgets 的 API 这样的大东西 我只想要可以在 Android iOS Windows Mac Linux 上运行的简单套接字 我正在制作一个事件驱动的纸牌游戏 所以 TCP 是最好的 本质上 我只想
  • 我应该害怕使用 UDP 进行客户端/服务器广播通话吗?

    我在过去的两天里阅读了每一篇StackOverflow问题和答案 以及googling当然 关于印地TCP and UDP协议 以便决定在我的用户应用程序和 Windows 服务之间的通信方法中应该使用哪一种 从我目前所看到的来看 UDP是
  • 无法分配请求的地址 - 可能的原因?

    我有一个由主服务器和分布式从服务器组成的程序 从属服务器向服务器发送状态更新 如果服务器在固定时间内没有收到特定从属服务器的消息 则会将该从属服务器标记为关闭 这种情况一直在发生 通过检查日志 我发现从站只能向服务器发送一个状态更新 然后永
  • 为什么 TCP 段中的 SYN 或 FIN 位会占用序列号空间中​​的一个字节?

    我试图理解这种设计背后的基本原理 我浏览了一些 RFC 但没有发现任何明显的东西 这并不是特别微妙 这样 SYN 和 FIN 位本身就可以被确认 因此如果丢失则可以重新发送 例如 如果连接关闭而没有发送更多数据 那么如果 FIN 没有发送任
  • TcpClient 在异步读取期间断开连接

    我有几个关于完成 tcp 连接的问题 客户端使用 Tcp 连接到我的服务器 在接受客户端后listener BeginAcceptTcpClient ConnectionEstabilishedCallback null 我开始阅读netw

随机推荐

  • HttpWebRequest 使用NetworkCredential 进行域认证下载时不成功 的解决方案

    最近在项目中使用pWebRequest 使用NetworkCredential 进行域认证下载时老不成功 xff0c 最后Google了解决方案 xff0c 发现几乎所有讨论的方案都不成功 xff0c 只好埋头自己解决 xff0c 最后总算
  • Firefox 的用户脚本管理器 greasemonkey 的使用一例

    一 什么是greasemonkey Firefox 的用户脚本管理器 greasemonkey 使你可以向任何网页添加DHTML语句 用户脚本 来改变它们的显示方式 就像CSS可以让你接管网页的样式 xff0c 而用户脚本 User Scr
  • Apache Http 服务器安装教程

    我在学习网络开发的时候需要从服务器上获得json数据 xff0c 所以在自己的电脑上安装了一个本地服务器 xff0c 其中遇到的一些问题 xff0c 在这里都写出来 首先 xff0c 我们需要访问apache http服务器的下载网页 xf
  • STM32的UART奇偶校验注意

    STM32的UART奇偶校验注意 STM32的UART在初始化时 xff0c 我们通常用到最多的就是无校验位 xff0c 1停止位 但是我在项目中也遇到某些芯片通信用的需要奇校验或者偶校验 xff0c 这里需要特别注意的是STM32中开启奇
  • Realtek RTL8762C/Realtek RTL8762D学习记录

    本人基于日常工作整理编写的8762C FAQ文档 xff0c 记录RTL8762C 8762D系列软件开发常见问题以及解决方案 希望它能发挥更多作用 帮到有需要的朋友 关键字 xff1a 8762CMF 8762CK 8762CJ 8762
  • 蓝牙BLE---DA14683的SPI主机通信讲解

    DA14683的SPI主机通信例程 Date 2018 12 19 Create Jim 导入例程 首先导入ble peripheral例程或者pxp reporter例程 再到以下位置打开硬件SPI的宏定义 xff1a 获取SPI例程源码
  • 06.5 Code

    06 5 Code 推力 force 推力的应用旋翼的气动阻力空气阻力矩滚转力矩电机的转速 推力 force span class token comment force 61 电机的转速 xff5c 电机的转速 xff5c xff08 带
  • C、C++ 对于char*和char[]的理解

    1 char 和char 的共同点 都是指针 xff0c 指向第一个字符所在的地址 2 char 的用法 char a 61 34 aaa 34 char p1 61 a char 是常量指针 xff08 常量的指针 xff09 xff0c
  • 重新抛出(rethrow)

    有可能单个catch不能完全处理一个异常 在进行了一些校正行动之后 xff0c catch可能确定该异常必须由函数调用链中更上层的函数来处理 xff0c catch可以通过重新抛出 rethrow 将异常传递给函数调用链中更上层的函数 重新
  • 4-2 图像聚类算法

    4 2 图像聚类算法 目录1 分类与聚类1 1 分类1 2 聚类1 3 聚类样本间的属性1 4 聚类的常见算法 2 K Means聚类2 1 概念2 2 步骤2 3 例子2 4 K Means聚类与图像处理2 5 K Means聚类优缺点优
  • JavaWeb-03 统一字符集编码、JSP的页面元素、JSP九大内置对象-request

    1 使用Eclipse开发Web项目 JSP项目 tomacat 2 在Eclipse中创建的Web项目 xff1a 浏览器可以直接访问WebContent中的文件例如 http 127 0 0 1 8888 MyJspProject in
  • 9-1 从零开始训练网络

    9 1 从零开始训练网络 目录1 搭建网络基本架构要完成的功能 2 构建训练网络1 实现网络训练功能2 获取训练数据及预处理 3 启动训练网络并测试数据 目录 搭建网络基本架构构建训练网络启动训练网络并测试数据 1 搭建网络基本架构 要完成
  • 基于知识图谱的推荐系统

    基于知识图谱的推荐系统 推荐系统 xff1a 核心目标是通过分析用户行为 兴趣 需求等信息 在海量的数据中挖掘用户感兴趣的信息 如商品 新闻 POI point of interest 和试题 等 个性化推荐算法是推荐系统的核心 其主要可以
  • mysql级联删除

    mysql级联删除 场景 xff1a 员工表 id xff1a 员工idleader id xff1a 该员工的领导的id xff08 也是员工id xff09 外键dept id xff1a 该员工的部门id xff08 部门表外键 xf
  • 【Seata】安装 - mac

    1 下载 官网 xff1a https seata io zh cn index html 2 修改配置文件 2 1 file conf 还有user password 2 2 registry conf 1 xff09 registry
  • Go Modules模式

    Go Modules模式 xff08 1 xff09 go mod 命令 命令作用go mod init生成 go mod 文件 在当前文件夹下初始化一个新的 go mod 文件go mod download下载 go mod 文件中指明的
  • 【Go】flag

    flag String span class token keyword func span span class token function String span span class token punctuation span n
  • Mybatis 逆向工程

    Mybatis 逆向工程 Maven项目generatorConfig xmlpom xml Maven项目 项目结构 xff1a generatorConfig xml span class token prolog lt xml ver
  • 原理分享 | 单片机常用通信协议汇总(上)

    vx 嵌入式工程师成长日记 https mp weixin qq com s biz 61 Mzg4Mzc3NDUxOQ 61 61 amp mid 61 2247484134 amp idx 61 1 amp sn 61 b779ccf0
  • C语言模拟TCP通信-------收发数据

    简介 这篇是我学习网络编程时初次接触到的 xff0c 感觉挺适合初学者 xff0c 下文主要介绍了如何使用Linux模拟TCP通信 xff0c 分为客户端和服务器端两大部分 xff0c 外加一个总的头文件 流程 服务器端和客户端使用TCP的