当前位置:网站首页>C语言:详细讲解基于tcp和udp的两种本地通信方式
C语言:详细讲解基于tcp和udp的两种本地通信方式
2022-07-23 05:44:00 【lhb2998658795】
一.本地通信(UNIX域套接字)
1.1概念
socket同样可以用于本地通信创建套接字时使用本地协议PF_UNIX(或PF_LOCAL)分为流式套接字和用户数据报套接字,区别还是有无连接常用于前后台进程通信。
使用的机构体
struct sockaddr_un {
sa_family_t sun_family; /* AF_UNIX */
char sun_path[108]; /* 路径及文件名 */
};1.2TCP本地通信流程
服务器:
创建套接字 socket( )
填充服务器本地信息结构体 sockaddr_un
将套接字与服务器本地信息结构体绑定 bind( )
将套接字设置为被动监听状态 listen( )
阻塞等待客户端的连接请求 accept( )
进行通信 recv( )/send( ) 或 read( )/write( )
客户端:
创建套接字 socket( )
填充服务器本地信息结构体 sockaddr_un
发送客户端的连接请求 connect( )
进行通信 send( )/recv( )
1.3代码实现
代码说明:这就是一个循环应答的一个代码,来讲解本地通信
服务器代码
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <arpa/inet.h>
#define ERRLOG(errmsg) do{\
printf("%s:%s:%d --", __FILE__, __func__, __LINE__);\
perror(errmsg);\
exit(-1);\
}while(0)
int main(int argc, const char *argv[]){
if(2 != argc){
printf("Usage : %s <filename>\n", argv[0]);
return -1;
}
//创建流式套接字
int sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
if(-1 == sockfd){
ERRLOG("socket error");
}
//填充信息本地信息结构体
struct sockaddr_un serveraddr;
memset(&serveraddr, 0, sizeof(serveraddr));
serveraddr.sun_family = AF_UNIX;
strcpy(serveraddr.sun_path, argv[1]);
socklen_t serveraddr_len = sizeof(serveraddr);
//绑定
if(-1 == bind(sockfd, (struct sockaddr *)&serveraddr, serveraddr_len)){
ERRLOG("bind error");
}
//监听
if(-1 == listen(sockfd, 5)){
ERRLOG("listen error");
}
//定义结构体保存对方的信息
struct sockaddr_un clientaddr;
memset(&clientaddr, 0, sizeof(clientaddr));
socklen_t clientaddr_len = sizeof(clientaddr);
int acceptfd = accept(sockfd, (struct sockaddr *)&clientaddr, &clientaddr_len);
if(-1 == acceptfd){
ERRLOG("accept error");
}
printf("客户端[%s]连接到服务器\n", clientaddr.sun_path);
char buff[128] = {0};
while(1){
if(-1 == recv(acceptfd, buff, 128, 0)){
ERRLOG("recv error");
}
printf("客户端[%s]发来数据[%s]\n", clientaddr.sun_path, buff);
strcat(buff, "--hqyj");
if(-1 == send(acceptfd, buff, 128, 0)){
ERRLOG("send error");
}
memset(buff, 0, 128);
}
close(acceptfd);
close(sockfd);
return 0;
}客户端
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <arpa/inet.h>
#define ERRLOG(errmsg) do{\
printf("%s:%s:%d --", __FILE__, __func__, __LINE__);\
perror(errmsg);\
exit(-1);\
}while(0)
int main(int argc, const char *argv[]){
if(2 != argc){
printf("Usage : %s <filename>\n", argv[0]);
return -1;
}
//创建流式套接字
int sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
if(-1 == sockfd){
ERRLOG("socket error");
}
//填充服务器本地信息结构体
struct sockaddr_un serveraddr;
memset(&serveraddr, 0, sizeof(serveraddr));
serveraddr.sun_family = AF_UNIX;
strcpy(serveraddr.sun_path, argv[1]);
socklen_t serveraddr_len = sizeof(serveraddr);
//定义客户端本地信息结构体
struct sockaddr_un clientaddr;
memset(&clientaddr, 0, sizeof(clientaddr));
clientaddr.sun_family = AF_UNIX;
strcpy(clientaddr.sun_path,"tcp_client_file");
socklen_t clientaddr_len = sizeof(clientaddr);
//客户端需要绑定,否则服务器收不到客户端的文件名
if(-1 == bind(sockfd, (struct sockaddr *)&clientaddr, clientaddr_len)){
ERRLOG("bind error");
}
if(-1 == connect(sockfd, (struct sockaddr *)&serveraddr, serveraddr_len)){
ERRLOG("accept error");
}
printf("连接服务器成功\n");
char buff[128] = {0};
while(1){
fgets(buff, 128, stdin);
buff[strlen(buff)-1] = '\0';
if(-1 == send(sockfd, buff, 128, 0)){
ERRLOG("send error");
}
if(-1 == recv(sockfd, buff, 128, 0)){
ERRLOG("recv error");
}
printf("应答[%s]\n", buff);
memset(buff, 0, 128);
}
close(sockfd);
return 0;
}二UDP本地通信
2.1流程
服务器:
创建套接字 socket( )
填充服务器本地信息结构体 sockaddr_un
将套接字与服务器本地信息结构体绑定 bind( )
进行通信 recvfrom( ) / sendto( )
客户端:
创建套接字 socket( )
填充客户端本地信息结构体 sockaddr_un
将套接字与客户端本地信息结构体绑定 bind()
填充服务器本地信息结构体 sockaddr_un
进行通信 sendto( ) / recvfrom( )
2.2代码实现
服务器
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <arpa/inet.h>
#define ERRLOG(errmsg) do{\
printf("%s:%s:%d --", __FILE__, __func__, __LINE__);\
perror(errmsg);\
exit(-1);\
}while(0)
int main(int argc, const char *argv[]){
if(2 != argc){
printf("Usage : %s <filename>\n", argv[0]);
return -1;
}
//创建用户数据报套接字
int sockfd = socket(AF_UNIX, SOCK_DGRAM, 0);
if(-1 == sockfd){
ERRLOG("socket error");
}
//填充服务器信息本地信息结构体
struct sockaddr_un serveraddr;
memset(&serveraddr, 0, sizeof(serveraddr));
serveraddr.sun_family = AF_UNIX;
strcpy(serveraddr.sun_path, argv[1]);
socklen_t serveraddr_len = sizeof(serveraddr);
//绑定
if(-1 == bind(sockfd, (struct sockaddr *)&serveraddr, serveraddr_len)){
ERRLOG("bind error");
}
//定义结构体保存对方的信息
struct sockaddr_un clientaddr;
memset(&clientaddr, 0, sizeof(clientaddr));
socklen_t clientaddr_len = sizeof(clientaddr);
char buff[128] = {0};
while(1){
if(-1 == recvfrom(sockfd, buff, 128, 0, (struct sockaddr *)&clientaddr, &clientaddr_len)){
ERRLOG("recv error");
}
printf("客户端[%s]发来数据[%s]\n", clientaddr.sun_path, buff);
strcat(buff, "--hqyj");
if(-1 == sendto(sockfd, buff, 128, 0, (struct sockaddr *)&clientaddr, clientaddr_len)){
ERRLOG("send error");
}
memset(buff, 0, 128);
}
close(sockfd);
return 0;
}客户端
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <arpa/inet.h>
#define ERRLOG(errmsg) do{\
printf("%s:%s:%d --", __FILE__, __func__, __LINE__);\
perror(errmsg);\
exit(-1);\
}while(0)
int main(int argc, const char *argv[]){
if(3 != argc){
printf("Usage : %s <server_filename> <client_filename>\n", argv[0]);
return -1;
}
//创建用户数据报套接字
int sockfd = socket(AF_LOCAL, SOCK_DGRAM, 0);
if(-1 == sockfd){
ERRLOG("socket error");
}
//填充服务器本地信息结构体
struct sockaddr_un serveraddr;
memset(&serveraddr, 0, sizeof(serveraddr));
serveraddr.sun_family = AF_UNIX;
strcpy(serveraddr.sun_path, argv[1]);
socklen_t serveraddr_len = sizeof(serveraddr);
//定义客户端本地信息结构体
struct sockaddr_un clientaddr;
memset(&clientaddr, 0, sizeof(clientaddr));
clientaddr.sun_family = AF_UNIX;
strcpy(clientaddr.sun_path, argv[2]);
socklen_t clientaddr_len = sizeof(clientaddr);
//客户端需要绑定,否则服务器收不到客户端的文件名
if(-1 == bind(sockfd, (struct sockaddr *)&clientaddr, clientaddr_len)){
ERRLOG("bind error");
}
char buff[128] = {0};
while(1){
fgets(buff, 128, stdin);
buff[strlen(buff)-1] = '\0';
if(-1 == sendto(sockfd, buff, 128, 0, (struct sockaddr *)&serveraddr, serveraddr_len)){
ERRLOG("send error");
}
//因为serveraddr没有变过 所以无需再保存了
if(-1 == recvfrom(sockfd, buff, 128, 0, NULL, NULL)){
ERRLOG("recv error");
}
printf("应答[%s]\n", buff);
memset(buff, 0, 128);
}
close(sockfd);
return 0;
}边栏推荐
- 高电压技术重点知识整理
- 【Autosar 存储Stack NVM】
- K-nucleotide frequencies (KNF) or k-mer frequencies
- 【AUTOSAR CanTP 1.学习UDS诊断的网络层协议】
- [learning summary]
- Jetson TX1安装 Pytorch
- 队列与堆的相互实现(纯c实现)
- Axure实现增删改查
- 【AUTOSAR COM 2.通信协议栈进阶介绍】
- The CUDA version of pytorch installed by anconda is inconsistent with the CUDA version of the system
猜你喜欢

【AUTOSAR COM 2.通信协议栈进阶介绍】

Blog building 4: how to add your blog to Baidu and Google

钢结构复习题

Interpretation of the paper: develop a prediction model based on multi-layer deep learning to identify DNA N4 methylcytosine modification

单片机学习笔记5--STM32时钟系统(基于百问网STM32F103系列教程)

单片机学习笔记8--按键和外部中断(基于百问网STM32F103系列教程)

【AUTOSAR COM 3.信号的收发流程TX/RX】

钢结构基本原理试题及答案

Interpretation of the paper: develop and verify the deep learning system to classify the etiology of macular hole and predict the anatomical results

Using pycaret: low code, automated machine learning framework to solve classification problems
随机推荐
Object class
switch实现表达式计算
【存储器了解 RAM flash和eeprom存储器的区别和作用】
Deep learning neural network
[introduction to AUTOSAR com 4.com service layer module]
Awk programming language
The CUDA version of pytorch installed by anconda is inconsistent with the CUDA version of the system
对字符串函数的使用和理解(1)
[AUTOSAR cantp 1. learn the network layer protocol of UDS diagnosis]
高电压技术重点知识整理
Blog Building II: next theme related settings beta
Data analysis of time series (II): Calculation of data trend
钢结构基本原理题库
Data analysis (I)
鋼結構基本原理複習
高等代数100道题及答案解析
Blog building 4: how to add your blog to Baidu and Google
单片机学习笔记6--中断系统(基于百问网STM32F103系列教程)
动态规划——“换硬币问题”
预处理指令#define,你真的懂了吗?