Linux网络编程:TCP编程实现

目录

1、前言

2、函数介绍

2.1 socket函数 与 通信域 

2.2 bind函数 与 通信结构体 

2.2.1 domain通信地址族 与 通信结构体 

2.2.2 IPv4地址族结构体 

2.2.3 通用地址族结构体 

2.2.4 示例:为套接字fd绑定通信结构体addr 

2.3 listen函数 与 accept函数 

3、代码实现

3.1 服务器端代码 

3.2 客户端代码 

3.3 构建Makefile 

4、实验结果 


1、前言

使用Linux操作系统实现TCP的客户端及服务器

TCP通信的实现过程示意图如下:

2、函数介绍

2.1 socket函数 与 通信域 

#include <sys/types.h>
#include <sys/socket.h>
int socket(int domain, int type, int protocol);
  • domain: 指定通信域(通信地址族),AF_INET: 使用IPv4 互联网协议;AF_INET6: 使用IPv6 互联网协议;
  • type: 指定套接字类型,TCP唯一对应流式套接字,所以选择SOCK_STREAM(数据报套接字:SOCK_DGRAM);
  • protocol: 指定协议,流式套接字唯一对应TCP,所以无需要指定协议,设为0即可。

2.2 bind函数 与 通信结构体 

int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
  • sockfd:socket函数生成的套接字
  • addr:通信结构体
  • addrlen:通信结构体的长度

2.2.1 domain通信地址族 与 通信结构体 

2.2.2 IPv4地址族结构体 

struct sockaddr_in {
    sa_family_t    sin_family; /* 地址族: AF_INET */
    in_port_t      sin_port;   /* 网络字节序的端口号 */
    struct in_addr sin_addr;   /*IP地址结构体 */
};
/* IP地址结构体 */
struct in_addr {
    uint32_t       s_addr;     /* 网络字节序的IP地址 */
};

2.2.3 通用地址族结构体 

struct sockaddr {
    sa_family_t sa_family;
    char        sa_data[14];
}

2.2.4 示例:为套接字fd绑定通信结构体addr 

addr.sin_family = AF_INET;
addr.sin_port = htons(5001);
addr.sin_addr.s_addr = 0;//本机地址
bind(fd, (struct sockaddr *)&addr, sizeof(addr) );

2.3 listen函数 与 accept函数 

/*监听套接字*/
int listen(int sockfd, int backlog);
/*处理客户端发起的连接,生成新的套接字*/
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
  • sockfd: 函数socket生成的套接字
  • addr:客户端的地址族信息
  • addrlen:地址族结构体的长度 

3、代码实现

3.1 服务器端代码 

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

#define BACKLOG 5

int main(int argc,char *argv[])
{
	int fd,newfd,ret;
	char buf[BUFSIZ] = {};//BUFSIZ 8142
	struct sockaddr_in addr;

	if(argc < 3)
	{
		printf("%s<addr><port>\n",argv[0]);
		exit(0);
	}

	/*创建套接字*/
	fd = socket(AF_INET,SOCK_STREAM,0);
	if(fd < 0)
	{
		perror("socket");
		exit(0);
	}
	addr.sin_family = AF_INET;
	addr.sin_port = htons(atoi(argv[2]));
	if(inet_aton(argv[1],&addr.sin_addr)==0)
	{
		fprintf(stderr,"Invalid address\n");
		exit(0);
	}

	/*绑定通信结构体*/
	if(bind(fd,(struct sockaddr *)&addr,sizeof(addr)) == -1)
	{
		perror("bind");
		exit(0);
	}
	/*设置套接字为侦听模式*/
	if(listen(fd,BACKLOG) == -1)
	{
		perror("listen");
		exit(0);
	}
	/*接受客户端的连接请求,生成新的用于和客户端通信的套接字*/
	newfd = accept(fd,NULL,NULL);
	if(newfd < 0)
	{
		perror("accept");
		exit(0);
	}
	printf("BUFSIZ = %d\n",BUFSIZ);
	while(1)
	{
		memset(buf,0,BUFSIZ);
		ret = read(newfd,buf,BUFSIZ);
		if(ret < 0 )
		{
			perror("read");
			exit(0);
		}
		else if(ret == 0)
			break;
		printf("buf = %s\n",buf);
	}
	close(newfd);
	close(fd);
	return 0;
}

3.2 客户端代码 

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

#define BACKLOG 5
int main(int argc,char *argv[])
{
	int fd;
	struct sockaddr_in addr;
	char buf[BUFSIZ] = {};
	if(argc < 3)
	{
		printf("%s<addr><port>\n",argv[0]);
		exit(0);
	}
	/*创建套接字*/
	fd = socket(AF_INET,SOCK_STREAM,0);
	if(fd < 0)
	{
		perror("socket");
		exit(0);
	}
	addr.sin_family = AF_INET;
	addr.sin_port = htons(atoi(argv[2]));
	if(inet_aton(argv[1],&addr.sin_addr)==0)
	{
		fprintf(stderr,"Invalid address\n");
		exit(0);
	}
	/*向服务端发起连接请求*/
	if(connect(fd,(struct sockaddr *)&addr,sizeof(addr)) == -1)
	{
		perror("connect");
		exit(0);
	}
	while(1)
	{
		printf("Input->");
		fgets(buf,BUFSIZ,stdin);
		write(fd,buf,strlen(buf));
	}
	close(fd);
	return 0;
}

3.3 构建Makefile 

Makefile文件如下: 


CC=gcc
CFLAGS=-Wall
all:client server

clean:
	rm client server

使用make去构建服务器和客户端程序。

在服务器端传入ip地址和端口号,本机地址写0,端口号写5001。

./server 0 5001

在客户端传入ip地址和端口号,连接地址写127.0.0.1(本地回环地址),端口号写5001。 

./client 127.0.0.1 5001

4、实验结果 

通过截图可以看到,测试成功,客户端发送消息,服务器端可以接收并打印。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/603681.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

onlyoffice容器打包成镜像

书接上篇&#xff0c;onlyoffice容器已经更改在本地docker环境中了&#xff0c;之后需要部署到测试环境的docker中&#xff0c;采用容器打包成本地镜像 1、本地docker 查看容器&#xff1a;docker ps 生成镜像&#xff1a;docker commit -p blissful_lichterman 重命名镜像&a…

MySql表的增删查改(CRUD)

对表中的数据操作分为4大类&#xff0c;增加数据&#xff0c;删除数据&#xff0c;查找数据&#xff0c;修改数据。对表中的数据进行增删查改操作简称为CRUD。Create(增),Retrieve(查找),Updata(修改&#xff09;,Delete(删除)CRUD的操作是对表中的数据进行操作的&#xff0c;是…

RTT PIN设备学习

获取GPIO编号 GET_PIN(port, pin)#define LED_BLUE_PIN GET_PIN(A, 0)设置引脚模式 void rt_pin_mode(rt_base_t pin, rt_base_t mode);设置引脚电平 void rt_pin_write(rt_base_t pin, rt_base_t value);rt_base_t pin 同上&#xff0c; 为引脚编号&#xff0c;尽量通过宏定…

c++ socket基于TCP

linux网络编程基础api socket 地址api&#xff1a;ip地址和端口对&#xff0c;成为 soccket 地址。 socket 基础api&#xff1a; sys/socket.h 中&#xff0c;包括创建、命名、监听 socket &#xff1b;接受连接、发起连接、读写数据、获取地址信息、检测带外标记、读取设置 s…

网络机顶盒哪个牌子好?经销商整理热门网络机顶盒排名

做实体数码店多年来&#xff0c;网络机顶盒这行我非常了解&#xff0c;各种品牌的网络机顶盒我们全销售过。近来很多朋友咨询我网络机顶盒哪个牌子好&#xff0c;我按照店内近一个季度的销量情况整理了是实体店最畅销的网络机顶盒排名&#xff0c;最受欢迎的品牌是以下这些&…

WM Shell多动画场景处理

Shell导致的内存泄漏 基本上都是某个动画未正常结束&#xff0c;执行时间太久导致后续动画堆积或被merge到异常动画导致相关Surface得不到释放导致的。 某个Transition执行时间太久导致后续动画堆积 Visible layers 中有1558 个Transition Root相关layer Visible layers (c…

卡牌——蓝桥杯十三届2022国赛大学B组真题

样例输入 4 5 1 2 3 4 5 5 5 5样例输出 3样例说明 这 5 张空白牌中,拿2张写1,拿1张写2,这样每种牌的牌数就变为了3,3,3,4, 可以凑出 3套牌,剩下2张空白牌不能再帮助小明凑出一套。 评测用例规模与约定 对于30%的数据&#xff0c;保证n ⩽ \leqslant ⩽ 2000; 对于100%的数据…

笔记85:如何计算递归算法的“时间复杂度”和空间复杂度?

先上公式&#xff1a; 递归算法的时间复杂度 递归次数 x 每次递归消耗的时间颗粒数递归算法的空间复杂度 递归深度 x 每次递归消耗的内存空间大小 注意&#xff1a; 时间复杂度指的是在执行这一段程序的时候&#xff0c;所花费的全部的时间&#xff0c;即时间的总和而空间复…

ORA-28575: unable to open RPC connection to external procedure agent

环境&#xff1a; Oracle 11.2.0.4x64 RAC AIX6.1版本SDE for aix oracle11g版本10.0 x64 sde配置情况如下&#xff1a; 检查oracle和grid用户下的$ORACLE_HOME/hs/admin/extproc.ora文件均包含有如下&#xff1a; SET EXTPROC_DLLSANY 两个节点sde下的user_libraries都正常…

【STM32+HAL+Proteus】系列学习教程---中断(NVIC、EXTI、按键)

实现目标 1、掌握STM32的中断知识 2、学会STM32CubeMX软件关于中断的配置 3、具体目标&#xff1a;1、外部中断检测按键&#xff0c;每按一次计一次数&#xff0c;满5次LED1状态取反。 一、中断概述 1.1、中断定义 CPU执行程序时&#xff0c;由于发生了某种随机的事件(包括…

巡检机器人有哪些功能和作用?

在科技如此发达的时代&#xff0c;巡检机器人犹如一位不知疲倦的守护者&#xff0c;悄然走进了我们的生活。它们具备着令人惊叹的功能和作用&#xff0c;成为了保障安全、提高效率的重要力量。那么&#xff0c;巡检机器人功能和作用&#xff1f;下面我们来说说旗晟机器人的几款…

faad2交叉编译——aac解码为pcm,解决faad单通道转双通道问题

FAAD是比较成熟高效的开源AAC解码库&#xff0c;这里用于解码AAC生成PCM数据&#xff0c;用于音频播放。这里因为faad库&#xff0c;会将单通道转化为双通道踩了些坑&#xff0c;所以记录一下。 我使用的是2.11.0版本&#xff0c;貌似往前的版本没有使用CMake&#xff0c;需要c…

自动化测试:Selenium入门指南!

Selenium是一个强大的自动化测试工具&#xff0c;特别适用于Web应用测试。本指南将介绍Selenium的安装、常用功能以及一些常见方法&#xff0c;帮助入门并能够更灵活地进行自动化测试。Selenium是一个用于自动化浏览器操作的工具&#xff0c;它广泛应用于Web应用程序的测试和网…

【前缀和】560. 和为 K 的子数组 974. 和可被 K 整除的子数组

题目链接 974. 和可被 K 整除的子数组 560. 和为 K 的子数组 今天刷题的时候&#xff0c;刷了这两题&#xff0c;感觉挺有意思的。代码写起来挺简单的&#xff0c;但是思路和其中的细节以及涉及到的知识点确实让我挺意外的。这里写个博客解析一波&#xff0c;也是巩固一下。 力…

分享《2024年中国企业级SaaS行业研究报告》

&#xff08;文章作者与来源&#xff1a;艾瑞咨询&#xff09; 大浪淘沙&#xff0c;SaaS行业进入关键转折点&#xff0c;企业级SaaS的总体市场规模达到888亿元&#xff0c;同比增长13.0%。内外部因素叠加之下&#xff0c;预计三年未来企业级SaaS市场规模的增速将稳定在15%-20…

请大数据把我推荐给正在申请小程序地理位置接口的人

小程序地理位置接口有什么功能&#xff1f; 若提审后被驳回&#xff0c;理由是“当前提审小程序代码包中地理位置相关接口( chooseAddress、getLocation )暂未开通&#xff0c;建议完成接口开通后或移除接口相关内容后再进行后续版本提审”&#xff0c;那么遇到这种情况&#x…

2024速通python之python基础

文章目录 一、你好&#xff0c;世界二、基本数据类型&#xff08;1&#xff09;数字型&#xff08;2&#xff09;字符串&#xff08;3&#xff09;列表&#xff08;4&#xff09;元组&#xff08;5&#xff09;集合&#xff08;6&#xff09;字典 二、注释&#xff08;1&#x…

【面试干货】http请求报文的组成与作用?

【面试干货】http请求报文的组成与作用&#xff1f; 一、http 的请求报文组成二、请求行&#xff08;Request Line&#xff09;三、请求头部&#xff08;Request Headers&#xff09;四、请求体&#xff08;Request Body&#xff09;五、响应头部 &#xff08;Response Headers…

LeetCode70:爬楼梯

题目描述 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢&#xff1f; 解题思想 1.确定dp数组以及下标的含义 dp[i]&#xff1a; 爬到第i层楼梯&#xff0c;有dp[i]种方法 2.确定递推公式 从dp[i]的定义可以…

Ansible任务剧本Playbook之变量、模板、角色介绍

前言 上篇介绍了 Ansible 单模块&#xff08;AD-Hoc&#xff09;的相关内容Ansible自动化运维工具单模块介绍-CSDN博客&#xff0c;Ad-Hoc 命令是一次性的、即时执行的命令&#xff0c;用于在远程主机上执行特定任务&#xff0c;这些命令通常用于快速执行简单的任务。当需要在…