udp通信程序(桥接模式)

news/2024/5/18 12:07:43 标签: udp, 网络协议, 网络

发送端 

#include "head.h"

int sockfd = 0;
pthread_t tid_send;
pthread_t tid_recv;
struct sockaddr_in recvaddr ;
char name[32];

void *sendfun(void *arg)
{
	struct msgbuf sendmsg;
	ssize_t nsize = 0;
	while(1)
	{
		memset(&sendmsg,0,sizeof(sendmsg));
		sendmsg.type = MSG_TYPE_CHAT;
		sprintf(sendmsg.name,"%s",name);
		gets(sendmsg.text);
				
		if (strcmp(sendmsg.text,".quit")==0)
		{
				sendmsg.type = MSG_TYPE_END;
		}

		nsize =sendto(sockfd,&sendmsg,sizeof(sendmsg),0,(struct sockaddr *)&recvaddr,sizeof(recvaddr));
		if(sendmsg.type == MSG_TYPE_END)
		{
			break;
		}
	}
	pthread_cancel(tid_recv);
	return NULL;
}

void *recvfun(void *arg)
{
	struct msgbuf recvmsg;
	ssize_t nsize = 0;

	while (1)
	{
		memset(&recvmsg, 0, sizeof(recvmsg));
		nsize = recvfrom(sockfd, &recvmsg, sizeof(recvmsg), 0, NULL, NULL);
		if (-1 == nsize)
		{
			perror("fail to recvfrom");
			return NULL;
		}

		if (recvmsg.type == MSG_TYPE_CHAT)
		{
			printf("%s(%s:%d)>%s\n", recvmsg.name, RECV_ADDR, RECV_PORT, recvmsg.text);
		}
		else if (recvmsg.type == MSG_TYPE_END)
		{
			break;
		}
	}

	pthread_cancel(tid_send);

	return NULL;
}
int main(void)
{
	struct msgbuf sendmsg;
	ssize_t nsize = 0;
	
	recvaddr.sin_family = AF_INET;
	recvaddr.sin_port = htons(RECV_PORT);
	recvaddr.sin_addr.s_addr = inet_addr(RECV_ADDR);
	printf("输入你的名字:");gets(name);

	sockfd = socket(AF_INET,SOCK_DGRAM,0);

	memset(&sendmsg,0,sizeof(sendmsg));
	sendmsg.type = MSG_TYPE_START;
	sprintf(sendmsg.name,"%s",name);
	nsize = sendto(sockfd,&sendmsg,sizeof(sendmsg),0,(struct sockaddr *)&recvaddr,sizeof(recvaddr));

	pthread_create(&tid_send,NULL,sendfun,NULL);
	pthread_create(&tid_recv,NULL,recvfun,NULL);
	
	pthread_join(tid_send,NULL);
	pthread_join(tid_recv,NULL);

	close(sockfd);

	return 0;
}

接收端

#include "head.h"

char name[32] = {0};
int sockfd = 0;
struct sockaddr_in recvaddr;
struct sockaddr_in sendaddr;
pthread_t tid_send;
pthread_t tid_recv;

void *sendfun(void *arg)
{
	struct msgbuf sendmsg;
	ssize_t nsize = 0;

	while (1)
	{
		memset(&sendmsg, 0, sizeof(sendmsg));
		sendmsg.type = MSG_TYPE_CHAT;
		sprintf(sendmsg.name, "%s", name);
		gets(sendmsg.text);
		
		if (!strcmp(sendmsg.text, ".quit"))
		{
			sendmsg.type = MSG_TYPE_END;
		}

		nsize = sendto(sockfd, &sendmsg, sizeof(sendmsg), 0, (struct sockaddr *)&sendaddr, sizeof(sendaddr));
		if (-1 == nsize)
		{
			perror("fail to sendto");
			return NULL;
		}

		if (sendmsg.type == MSG_TYPE_END)
		{
			break;
		}
	}

	pthread_cancel(tid_recv);
	
	return NULL;
}

void *recvfun(void *arg)
{
	struct msgbuf recvmsg;
	ssize_t nsize = 0;

	while (1)
	{
		memset(&recvmsg, 0, sizeof(recvmsg));
		nsize = recvfrom(sockfd, &recvmsg, sizeof(recvmsg), 0, NULL, NULL);
		if (-1 == nsize)
		{
			perror("fail to recvfrom");
			return NULL;
		}

		if (recvmsg.type == MSG_TYPE_CHAT)
		{
			printf("%s(%s:%d)>%s\n", recvmsg.name, inet_ntoa(sendaddr.sin_addr), ntohs(sendaddr.sin_port), recvmsg.text);
		}
		else if (recvmsg.type == MSG_TYPE_END)
		{
			break;
		}
	}
	
	pthread_cancel(tid_send);

	return NULL;
}

int main(void)
{
	struct msgbuf recvmsg;
	ssize_t nsize = 0;
	int ret = 0;
	socklen_t addrlen = sizeof(sendaddr);

	recvaddr.sin_family = AF_INET;
	recvaddr.sin_port = htons(RECV_PORT);
	recvaddr.sin_addr.s_addr = inet_addr(RECV_ADDR);

	printf("请输入您的昵称:\n");
	gets(name);

	sockfd = socket(AF_INET, SOCK_DGRAM, 0);
	if (-1 == sockfd)
	{
		perror("fail to socket");
		return -1;
	}
	
	ret = bind(sockfd, (struct sockaddr *)&recvaddr, sizeof(recvaddr));
	if (-1 == ret)
	{
		perror("fail to bind");
		return -1;
	}

	memset(&recvmsg, 0, sizeof(recvmsg));
	nsize = recvfrom(sockfd, &recvmsg, sizeof(recvmsg), 0, (struct sockaddr *)&sendaddr, &addrlen);
	if (-1 == nsize)
	{
		perror("fail to recvfrom");
		return -1;
	}

	pthread_create(&tid_send, NULL, sendfun, NULL);
	pthread_create(&tid_recv, NULL, recvfun, NULL);

	pthread_join(tid_send, NULL);
	pthread_join(tid_recv, NULL);

	close(sockfd);

	return 0;
}

.UDP编程
   


    1.发端:

socket套接字 编程:
        socket 
        int socket(int domain, int type, int protocol);
        功能:
            创建一个用来通信的文件描述符
        参数:
            domain:使用的协议族 AF_INET (IPv4协议族)
            type:套接字类型
                SOCK_STREAM:流式套接字
                SOCK_DGRAM:数据报套接字
                SOCK_RAW:原始套接字
            protocol:协议
                默认为0 
        返回值:
            成功返回文件描述符
            失败返回-1 

        sendto 
        ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
                      const struct sockaddr *dest_addr, socklen_t addrlen);
        功能:
            利用套接字向指定地址发送数据信息 
        参数:
            sockfd:套接字文件描述符
            buf:发送数据空0间首地址
            len:发送数据的长度
            flags:属性默认为0 
            dest_addr:目的地址信息存放的空间首地址
            addrlen:目的地址的长度
        
        struct sockaddr_in {
            sa_family_t    sin_family; /* address family: AF_INET */
            in_port_t      sin_port;   /* port in network byte order */
            struct in_addr sin_addr;   /* internet address */
        };

        /* Internet address. */
        struct in_addr {
            uint32_t       s_addr;     /* address in network byte order */
        };
                  
        返回值:
            成功返回实际发送字节数
            失败返回-1 

        inet_addr:
        in_addr_t inet_addr(const char *cp);
        功能:  
            将字符串IP地址转换为内存中的IP地址 

        htons
        uint16_t htons(uint16_t hostshort);
        功能:
            将本地字节序转换为网络的大端字节序
        
        close 

收端


1.recvfrom
    ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
                        struct sockaddr *src_addr, socklen_t *addrlen);
    功能:
        从套接字中接收数据
    参数:
        sockfd:套接字文件描述符
        buf:存放数据空间首地址
        flags:属性 默认为0 
        src_addr:存放IP地址信息的空间首地址
        addrlen:存放接收到IP地址大小空间的首地址
    返回值:
        成功返回实际接收字节数
        失败返回-1 
2.bind 
    int bind(int sockfd, const struct sockaddr *addr,
                socklen_t addrlen);
    功能:
        在套接字上绑定一个IP地址和端口号
    参数:
        sockfd:套接字文件描述符
        addr:绑定IP地址空间首地址
        addrlen:绑定IP地址的长度
    返回值:
        成功返回0 
        失败返回-1 


    发端:socket -> sendto -> close 
    收端: socket -> bind -> recvfrom -> close 
 


http://www.niftyadmin.cn/n/5422609.html

相关文章

通讯协议制定之数据消息传输方式介绍

文章目录 通讯协议制定之数据消息传输方式介绍1. 前言2. 介绍2种数据消息传输方式2.1 固定格式顺序传输方式2.2 添加signal id标记的传输方式 3. 小结 通讯协议制定之数据消息传输方式介绍 1. 前言 通讯协议又称通信规程,是指通信双方对数据传送控制的一种约定&am…

虚拟机Centos8登陆之后又弹回到登陆界面

今天开机发行,虚拟机Centos登陆之后又弹回到登陆界面,在网上一通搜索之后,发现Centos7正确输入账号密码后,循环进入输入账号密码界面(情况一设置错误PATH),以及进入单用户模式_centos一直卡在用…

CH343 使用USB转串口发送CAN报文

文章目录 原启UART 走CAN收发器CH343 模拟CAN发送CPP ASIO SocketCANVXCANGithub Link 原启 早些年自动驾驶激光雷达还不支持PTP之类的时间同步, 很多都是用PPS时间同步, 激光雷达一般装的离控制器或者GNSS天线较远, 车上的线束一般数据电源各种都包在一起的, 如果3.3V直接从域…

VMware Workstation Pro17 详细安装步骤

VMware Workstation(中文名“威睿工作站”)是一款功能强大的桌面虚拟计算机软件,提供用户可在单一的桌面上同时运行不同的操作系统,和进行开发、测试 、部署新的应用程序的最佳解决方案。VMware Workstation可在一部实体机器上模拟…

css之常用样式

展示样式一&#xff1a; <div class"showListBox"><div class"List" v-for"(i,index) in sealList" :key"index"> <div class"ListItemCon"><div class"ListItem-titleBox"><img src…

LeetCode 174.地下城游戏 Python题解

地下城游戏 # 地下城游戏 """ 恶魔们抓住了公主并将她关在了地下城dungeon的右下角。地下城是由mxn个房间组成的二维网格。我们英勇的骑士最初被安置在左上角的房间里&#xff0c; 他必须穿过地下城并通过对抗恶魔来拯救公主。 骑士的初始健康点数为一个正整数…

《计算机网络》考研:2024/3/6 2.1.2-数据通信基础知识(1)、2.1.3-数据通信基础知识(2)

2024/3/6 2.1.2、2.1.3 数据通信基础知识&#xff08;1&#xff09; Ch1. 典型的数据通信模型 典型的数据通信模型 Ch2. 数据通信相关术语 通信的目的是传送消息&#xff08;消息&#xff1a;语音、文字、图像和视频等&#xff09; 数据data&#xff1a;传送信息的实体&…

Redis常见数据类型下

目录 Hash 哈希 常用指令 HSET HGET HEXISTS HDEL HKEYS HVALS HGETALL HMGET 内部编码 Hash类型和关系型数据库 缓存方式对比 List 列表 特点 常用命令 LPUSH LPUSHX RPUSH RPUSHX LRANGE LPOP / RPOP LINDEX LINSERT 阻塞(BLOCK)版…