【Linux】UDP编程流程

UDP

一、定义
UDP是无连接不可靠的数据报服务
二、UDP服务器的系统调用
1、方法
(1)int socket();创建一个用于监听客户端连接的网络套接字
原型:

  • int socket(int domain, int type, int protocol)

成功返回套接字的文件描述符,失败返回-1
domain:协议簇 SOCK_DGRAM
type:具体的协议 SOCK_STREAM(TCP) SOCK_DGRAM(UDP)
protocol:默认值为0

(2)int bind();将创建的套接字与本端的地址信息进行绑定
原型:

  • int bind(int sockfd,const struct sockaddr * addr, socklen_t addrlen)

成功返回0,失败返回-1
sockfd:使用socket方法创建的套接字描述符
addr:服务器程序的地址信息
addr_len:指定结构体大小

(3)int recvfrom();接收任意一个客户端的数据
原型:

  • ssize_t sendto(int sockfd,const void * buf,size_t len, int flags,const
    struct sockaddr*dest_addr, socklen_t addrlen)

(4)int sendto();给一个客户端返送数据
原型:

  • ssize_t recvfrom(int sockfd, void * buf, size_t len, int flags, struct
    sockaddr*src_addr, socklen_t * addrlen)

(5)int close();释放数据
2、代码

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<assert.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>
int main()
{
	int sockfd = socket(AF_INET,SOCK_DRGAM, 0);
	assert(sockfd != -1);
	struct sockaddr_in ser_addr;
	memset(&ser_addr, 0, sizeof(ser_addr));
	ser_addr.sin_family = AF_INET;
	ser_addr.sin_port = thons(6000);
	ser_addr.sin_addr.s_addr = inet_addr("192.168.141.128");
	int res = bind(sockfd, (struct sockaddr*)&ser_addr, sizeof(ser_addr));
	assert(res != -1)
	while(1)
	{
		char buff[128] = {0};
		struct sockaddr_in cli_addr;
		socklen_t len = sizeof(cli_addr);
		int n = recvfrom(sockfd, buff, 127, 0, (struct sockaddr*)&cli_addr, &len);
		if(n <= 0)
		{
			printf("recvfrom error\n");
			continue;
		}
		printf("%s:%d --> %s\n", inet_ntoa(cli_addr.sin_addr), ntohs(cli_addr.sin_port), buff);
		int res = sendto(sockfd, "OK", 2, 0, (struct sockaddr*)&cli_addr, len);
		if(res <= 0)
		{
			printf("sendto error\n");
			continue;
		}
	}	
	close(sockfd);
	exit(0);

}

三、UDP客户端的系统调用
1、方法
(1)int socket();创建一个用于整个通讯的套接字
(2)int sendto();给一个客户端返送数据
(3)int recvfrom();接收任意一个客户端的数据
(4)int close();
2、代码

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<assert.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>
int main()
{
	int sockfd = socket(AF_INET,SOCK_DRGAM, 0);
	assert(sockfd != -1);
	struct sockaddr_in ser_addr;
	memset(&ser_addr, 0, sizeof(ser_addr));
	ser_addr.sin_family = AF_INET;
	ser_addr.sin_port = thons(6000);
	ser_addr.sin_addr.s_addr = inet_addr("192.168.141.128");
	while(1)
	{
		printf("intput: ");
		char buff[128] = {0};
		fgets(buff, 127, stdin);
		if(strncmp(buff, "end", 3) == 0)
		{
			break;
		}
		int res = sendto(sockfd, buff, strlen(buff) - 1, 0, (struct sockaddr*)&ser_addr, sizeof(ser_addr));
		assert(res != -1)
		memset(buff, 0, 128);
		int n = recvfrom(sockfd, buff, 127, 0, NULL, NULL);
		assert(n != -1)
		printf("recvfrom data: %s\n", buff);
    }
    close(sockfd);
    exit(0);
}

在这里插入图片描述
前两个是第一个客户端发送的数据,后三个是第二个客户端发送的数据
四、UDP协议与TCP字节流的特点
1、UDP数据报服务的特点:一次sendto表示发送了一段数据,接收方一次recvfrom如果没有将一次sendto发送的数据接收完,则剩余的数据就会被丢弃。
如下图所示:
在这里插入图片描述
2、TCP字节流的特点:
(1)send和recv的次数是没有直接关系的
(2)发送端send的次数与底层tcp报文段的个数也是没关系的
(3)一次recv如果没有将数据读取完成,剩余的数据会继续保存在接收缓冲区中,下次recv会接着上一次的位置读取

如下图所示:
在这里插入图片描述

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值