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 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 在Ubuntu18.04中的两个程序(基于C++)的UDP通信 -> 正文阅读

[C++知识库]在Ubuntu18.04中的两个程序(基于C++)的UDP通信

此文章将展示两个C++应用程序,这个应用中都分别定义了作为Serve和Client的部分,便于相互发送和接收测试。

测试分为两部分,第一部分测试是字符串的发送和接收,第二部分测试是结构体的发送和接收(其实也是先转化为字符串发送,接收后再转化为结构体的方式)

使用者可对相应部分进行注释和取消注释,以分别测试这两个功能。

源文件:
在这里插入图片描述

~代码

Code1:这段代码用作发送(实际稍作修改后发送和接收都可)

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <iostream>
#include <cstring>
#include <vector>
#include <unistd.h>
#include <typeinfo> 

using namespace std;
//创建新的套接字之前需要调用一个引入Ws2_32.dll库的函数,否则服务器和客户端连接不上
#pragma comment(lib,"ws2_32.lib")

struct TEST
{
	int test;
};
struct INFO
{
	int year;
	int month;
	int day;
	TEST test_struct;
	double temperature;
};

int main(int argc, char* argv[])
{
	struct sockaddr_in Server;				//创建服务端sockaddr_in结构体
	//建立一个数据报类型的UDP套接字  ******************//
	int serverSocket = socket(PF_INET, SOCK_DGRAM, 0); //配置模式,
	//设置服务器地址addrSrv和监听端口
	Server.sin_family = AF_INET;
	Server.sin_addr.s_addr = inet_addr("127.0.0.1"); //设置服务器主机ip地址(与接收方客户端的IP对应)
	Server.sin_port = htons(8001);					 //发送用的端口,可以根据需要更改


	//使用bind()函数绑定监听端口,将socket文件描述符sockSrv与地址类型变量(struct sockaddr_in )进行绑定
	//int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
	bind(serverSocket, (sockaddr *)&Server, sizeof(sockaddr));

	//*************************************************************************************************************//
	struct sockaddr_in Client;				//创建客户端sockaddr_in结构体
	int clientSocket = socket(PF_INET, SOCK_DGRAM, 0); //配置模式,
	Client.sin_family = AF_INET;
	Client.sin_addr.s_addr = inet_addr("127.0.0.3");
	Client.sin_port = htons(8001);


//*************************************************************************************************************//
	
	//创建发送和接受的结构体以及转化时用到的字符串,用作测试
	INFO sendinfo,recvinfo;
	char send_info_buf[100], recv_info_buf[100];
	//创建发送和接受的字符串,用作测试
	char sendbuf[100]= "How are you?", recvbuf[100];
	//对发送的结构体成员赋值
	sendinfo.year = 2021;
	sendinfo.month = 7;
	sendinfo.day = 27;
	sendinfo.test_struct.test = 10;
	sendinfo.temperature = 23.50;
	//将发送的结构体sendinfo转化为字符串send_info_buf
	memcpy(send_info_buf, &sendinfo, sizeof(sendinfo));
//************************************************************************************************************//

	while (1)
	{	
		usleep(2000000);
		//发送
			/*  
				int sendto(int s, const void* buf, int len, unsigned int flags, const struct sockaddr* to, int tolen);
				s:            接收端的socket描述符
				buf:    UDP数据报缓存区(包含待发送数据)
				len:     UDP数据报长度
				flags: 调用方式标志位(一般设置为0)
				to:      指向接收数据的主机地址信息的结构体,(sockaddr_in需类型转换);
				tolen:所指的结构体的长度
			*/	
			//字符串发送和打印所用语句
			//int t = sendto(clientSocket, sendbuf, sizeof(sendbuf), 0, (sockaddr*)&Client, sizeof(Client));	
			//cout << "sendto_len:  "<<t << endl<< endl;//若发送失败。则返回-1	
			//结构体发送和打印所用语句
			int t = sendto(clientSocket, send_info_buf, sizeof(send_info_buf)+1  , 0, (sockaddr*)&Client, sizeof(Client));
			cout << "sendto_len:  "<<t << endl<< endl;//若发送失败。则返回-1

		//接收
			/*  
				int recvfrom(int s, void *buf, int len, unsigned int flags,struct sockaddr *from, int *fromlen);
				s:       socket描述符
				buf:    UDP数据报缓存区(包含所要接受数据)
				len:    缓存区长度
				flags:  调用方式标志位(一般设置为0)
				from:   指向发送数据的客户端地址信息的结构体,(sockaddr_in需类型转换);
				fromlen:指针,指向from中结构体的长度
			*/

			//字符串接收和打印所用语句
			//socklen_t len = sizeof(sockaddr);
			//recvfrom(serverSocket, recvbuf, sizeof(recvbuf), 0, (sockaddr*)&Server, &len);
			//printf("%s\n\n", recvBuf);

			//结构体接收和打印所用语句
			//recvfrom(serverSocket, recv_info_buf, sizeof(recv_info_buf), 0, (sockaddr *)&Server, &len);
			//memcpy(&recvinfo, recv_info_buf, sizeof(recv_info_buf));
			//cout << "Today is  " << recvinfo.year << "." << recvinfo.month<<"." << recvinfo.day << endl;
			//cout << "The template is " << recvinfo.temperature << endl;
			//cout << "The struct-test number is " << recvinfo.test_struct.test << endl<< endl;
			
	}
	//closesocket(sockClient);
	close(serverSocket);
	return 0;
}

Code2:这段代码用作接收(实际稍作修改后发送和接收都可)

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <iostream>
#include <cstring>
#include <vector>
#include <unistd.h>
#include <typeinfo> 

using namespace std;
//创建新的套接字之前需要调用一个引入Ws2_32.dll库的函数,否则服务器和客户端连接不上
#pragma comment(lib,"ws2_32.lib")

struct TEST
{
	int test;
};
struct INFO
{
	int year;
	int month;
	int day;
	TEST test_struct;
	double temperature;
};

int main(int argc, char* argv[])
{	
	struct sockaddr_in Server;				//创建服务端sockaddr_in结构体
	//建立一个数据报类型的UDP套接字  ******************//
	int serverSocket = socket(PF_INET, SOCK_DGRAM, 0); //配置模式,
	//设置服务器地址addrSrv和监听端口
	Server.sin_family = AF_INET;
	Server.sin_addr.s_addr = inet_addr("127.0.0.3"); //设置服务器主机ip地址(与接收方客户端的IP对应)
	Server.sin_port = htons(8001);					 //发送用的端口,可以根据需要更改
	//使用bind()函数绑定监听端口,将socket文件描述符sockSrv与地址类型变量(struct sockaddr_in )进行绑定
	//int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
	bind(serverSocket, (sockaddr *)&Server, sizeof(sockaddr));

	//*******************************************************************************************//
	struct sockaddr_in Client;				//创建客户端sockaddr_in结构体
	int clientSocket = socket(PF_INET, SOCK_DGRAM, 0); //配置模式,
	Client.sin_family = AF_INET;
	Client.sin_addr.s_addr = inet_addr("127.0.0.1");
	Client.sin_port = htons(8001);

//*******************************************************************************************************
	//创建发送和接受的结构体以及转化时用到的字符串,用作测试
	INFO sendinfo,recvinfo;
	char send_info_buf[100], recv_info_buf[100];
	//创建发送和接受的字符串,用作测试
	char sendbuf[100]= "Hello!", recvbuf[100];
	//对发送的结构体成员赋值
	sendinfo.year = 1999;
	sendinfo.month = 11;
	sendinfo.day = 20;
	sendinfo.test_struct.test = 10;
	sendinfo.temperature = 18.30;
	//将发送的结构体sendinfo转化为字符串send_info_buf
	memcpy(send_info_buf, &sendinfo, sizeof(sendinfo));
//********************************************************************************************************

	while (1)
	{	
		
		//发送
			/*  
				int sendto(int s, const void* buf, int len, unsigned int flags, const struct sockaddr* to, int tolen);
				s:     接收端的socket描述符
				buf:  UDP数据报缓存区(包含待发送数据)
				len:  UDP数据报长度
				flags:调用方式标志位(一般设置为0)
				to:   指向接收数据的主机地址信息的结构体,(sockaddr_in需类型转换);
				tolen:同所指的结构体的长度
			*/	
			//字符串发送和打印所用语句
			//int t = sendto(clientSocket, sendbuf, sizeof(sendbuf), 0, (sockaddr*)&Client, sizeof(Client));	
			//cout << "sendto_len:  "<<t << endl;//若发送失败。则返回-1	
			//结构体发送和打印所用语句
			//int t = sendto(clientSocket, send_info_buf, sizeof(send_info_buf)+1  , 0, (sockaddr*)&Client, sizeof(Client));
			//cout << "sendto_len:  "<<t << endl<<endl;//若发送失败。则返回-1

		//接收
			/*  
				int recvfrom(int s, void *buf, int len, unsigned int flags,struct sockaddr *from, int *fromlen);
				s:       socket描述符
				buf:    UDP数据报缓存区(包含所要接受数据)
				len:    缓存区长度
				flags:  调用方式标志位(一般设置为0)
				from:   指向发送数据的客户端地址信息的结构体,(sockaddr_in需类型转换);
				fromlen:指针,指向from中结构体的长度
			*/
			socklen_t len = sizeof(sockaddr);
			//字符串接收和打印所用语句
			//recvfrom(serverSocket, recvbuf, sizeof(recvbuf), 0, (sockaddr*)&Server, &len);
			//printf("%s\n\n", recvbuf);

			//结构体接收和打印所用语句
			recvfrom(serverSocket, recv_info_buf, sizeof(recv_info_buf), 0, (sockaddr *)&Server, &len);
			memcpy(&recvinfo, recv_info_buf, sizeof(recv_info_buf));
			cout << "Today is  " << recvinfo.year << "." << recvinfo.month<<"." << recvinfo.day << endl;
			cout << "The template is " << recvinfo.temperature << endl;
			cout << "The struct-test number is " << recvinfo.test_struct.test << endl<<endl;
	}
	close(clientSocket);
	//close(serverSocket);
	return 0;
}

~编译

可用以下命令编译对应源代码:

g++ Code1.cpp -o Code1
g++ Code2.cpp -o Code2

生成可执行文件:在这里插入图片描述若未安装g++,可用以下命令安装

sudo apt-get install g++

输入密码后按步骤提示即可安装

~执行

可用以下命令执行对应可执行文件:

./Code1
./Code2

~效果

在这里插入图片描述
反向的发送和接收可尝试后自行测试

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-07-29 11:27:16  更:2021-07-29 11:29:27 
 
开发: 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年4日历 -2024/4/28 20:50:08-

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