IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> 封装tcp和udp网络通信 -> 正文阅读

[网络协议]封装tcp和udp网络通信

tcp和udp网络通信的封装

在写项目的时候,我们发现,tcp和udp的网络通信模型有很多的相似之处,因此我们可以考虑将其封装成一个函数,集成相关的函数,方便我们后面项目的使用。

代码展示:

network.h:

#ifndef NETWORK_H
#define NETWORK_H

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

typedef struct NetWork
{
	int type;					//通信协议的类型 SOCK_STREAM SOCK_DGRAM
	int sock_fd;				//socket描述符
	struct sockaddr_in addr;	//通信地址
	socklen_t addrlen;			//结构体字节数
	bool is_srv;				//是否是服务端
}NetWork;

typedef struct sockaddr* SP;

//分配内存,创建socket,准备地址,绑定,监听,连接
NetWork* init_nw(int type,const char* ip,short port,bool is_srv);
//等待连接,只有tcp服务端可以用,SOCK_STREAM
NetWork* accept_nw(NetWork* nw);
//具备send和sendto的发送函数
int send_nw(NetWork* nw,const void* buf,size_t len);
//具备recv和recvform的接收函数
int recv_nw(NetWork* nw,void* buf,size_t len);
//关闭socket并且释放内存
void close_nw(NetWork* nw);

#endif

network.c:

/**************************************************
>	作	  者:杭电羊皮卷
>   文件名称: network.c
>	联系方式:2997675141@qq.com
>   创建日期:2022年09月07日
>   描    述:网络通信的封装tcp和udp
**************************************************/

#include "network.h"

#define handle_error(msg)\
	do{perror(msg);free(nw);return NULL;}while(0)

//分配内存,创建socket,准备地址,绑定,监听,连接
NetWork* init_nw(int type,const char* ip,short port,bool is_srv)
{
	NetWork* nw = (NetWork* )malloc(sizeof(NetWork));
	nw->type = type;
	nw->is_srv = is_srv;
	nw->addrlen = sizeof(struct sockaddr_in);
	//创建socket
	nw->sock_fd = socket(AF_INET,type,0);
	if(nw->sock_fd < 0)
	{
		handle_error("socket");
	}
	//准备通信地址
	nw->addr.sin_family = AF_INET;
	nw->addr.sin_port = htons(port);
	nw->addr.sin_addr.s_addr = inet_addr(ip);

	//只有服务器才绑定
	if(is_srv)
	{
		if(0 > bind(nw->sock_fd,(SP)&(nw->addr),nw->addrlen))
		{
			handle_error("bind");
		}
	}
	//监听 服务器tcp才监听
	if(nw->type == SOCK_STREAM && nw->is_srv)
	{
		if(0 > listen(nw->sock_fd,20))
		{
			handle_error("listen");
		}
	}
	//连接,只有tcp的客户端才连接
	if(nw->is_srv == 0 && type == SOCK_STREAM)
	{
		int ret = connect(nw->sock_fd,(SP)&nw->addr,nw->addrlen);
		if(ret < 0)
		{
			handle_error("connect");
		}
	}
	return nw;
}
//等待连接,只有tcp服务端可以用,SOCK_STREAM
NetWork* accept_nw(NetWork* nw)
{
	if(nw->type == SOCK_STREAM && nw->is_srv)
	{
		NetWork* new = (NetWork* )malloc(sizeof(NetWork));
		new->type = nw->type;
		new->is_srv = true;
		new->addr = nw->addr;
		new->addrlen = nw->addrlen;
		new->sock_fd = accept(nw->sock_fd,(SP)&nw->addr,&(nw->addrlen));
		if(new->sock_fd < 0)
		{
			//handle_error("accept");
			perror("accept");
			free(new);
			return NULL;
		}
		return new;
	}
	return NULL;
}
//具备send和sendto的发送函数
int send_nw(NetWork* nw,const void* buf,size_t len)
{
	int ret;
	if(nw->type == SOCK_STREAM)
	{
		//tcp的发送
		ret = send(nw->sock_fd,buf,len,0);
	}
	else
	{
		//udp的发送
		ret = sendto(nw->sock_fd,buf,len,0,(SP)&(nw->addr),nw->addrlen);
	}
	return ret;
}
//具备recv和recvform的接收函数
int recv_nw(NetWork* nw,void* buf,size_t len)
{
	int ret;
	if(nw->type == SOCK_STREAM)
	{
		//tcp
		ret = recv(nw->sock_fd,buf,len,0);
	}
	else
	{
		ret = recvfrom(nw->sock_fd,buf,len,0,(SP)&(nw->addr),&(nw->addrlen));
	}
	return ret;
}
//关闭socket并且释放内存
void close_nw(NetWork* nw)
{
	close(nw->sock_fd);
	free(nw);
}

制作动态库:

首先我们考虑在用户主目录中创建两个目录,一个用于存放自己制作的动态库,一个用来存放在自己的头文件,所以在命令行中输入以下两个命令。

mkdir ~/lib

mkdir ~/include

其中lib用来存放动态库文件(.so文件),include存放头文件(.h文件)

然后添加这两个文件加进环境变量中

输入vim ~/.bashrc,这个文件是系统的配置文件,切记不要去修改,按下大写的G直接跳转到文末,然后按i进入插入模式,输入以下几行命令

export LIBRARY_PATH=$LIBRARY_PATH:/home/ubuntu/lib			//添加静态库查找路径
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/ubuntu/lib	//添加动态库加载路径
export C_INCLUDE_PATH=$C_INCLUDE_PATH:/home/ubuntu/include	//添加头文件查找路径

然后ctrl+c退出编辑模式,大写的两个Z退出文件

输入命令source ~/.bashrc该命令可以使系统配置文件立即生效

一切准备工作就绪,接下来制作动态库,将工作目录调整到network.cnetwork.h所在路径

先后输入命令

gcc -c -fpic network.c

gcc -shared network.o -o libnw.so

然后用ls -l命令查看可以看到多了一个可执行文件

libnw.so文件复制到~/lib文件

network.h文件复制到~/include文件

cp libnw.so ~/lib

cp network.h ~/include

然后就可以使用该库文件啦,使用方式和数学库一样的,在进行gcc编译的时候需要加载库文件

如:gcc main.c -lnw就可以正常编译了

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-09-13 11:52:32  更:2022-09-13 11:55:35 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/28 6:22:20-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计