目录
UDP 通信流程
udp通信协议的流程和实现步骤
发送端:socket --》bind --》sendto --》close
接收端:socket --》bind --》recvfrom --》close
UDP 发送端解释
创建套接字 (socket)
int socket(int domain, int type, int protocol);
返回值:
成功 返回套接字的文件描述符
失败 -1
参数:
domain //地址协议族
/*
AF_INET //ipv4地址
AF_INET6 //ipv6地址
*/
type //套接字类型
/*
udp套接字 SOCK_DGRAM
tcp套接字 SOCK_STREAM
*/
protocol //扩展协议,一般设置为0
绑定ip和端口(bind)
int bind(int socket,const struct sockaddr* my_addr,int addrlen);
返回值:
成功 0
失败 -1
参数:
socket //刚才创建好的套接字
my_addr //保存需要绑定ip和端口号
struct sockaddr //通用地址结构体,兼容ipv4和ipv6的
struct sockaddr_in //ipv4地址结构体
{
sin_family; //地址协议族AF_INET
sin_addr; //它也是个结构体,存放要绑定的ip
{
s_addr; //最终用来存放ip地址
}
sin_port; //存放要绑定的端口号
}
struct sockaddr_in6 //ipv6地址结构体
addrlen //地址结构体大小 sizeof
ip地址和端口号的转换:
- 大端序:数据的高字节存放在低地址,低字节存放在高地址
- 小端序:数据的高字节存放在高地址,低字节存放在低地址
- linux系统中:数据采用小端序存储
- 计算机网络中:数据采用大端序存储
第一个:转换ip地址
in_addr_t inet_addr(const char* strptr);
返回值:
转换成功赋值给ipv4地址结构体中sin_addr
参数:
strptr //要转换的ip地址
第二个:转换端口号
u_short htons(u_short hostshort);
返回值:
转换成功赋值给ipv4地址结构体中sin_port
参数:
hostshort //你指定的端口号
发送信息(sendto)
int sendto(int sock ,void * msg,int len,unsigned int flags,struct sockaddr *to ,int tolen)
返回值:
成功 返回发送的字节数
失败 -1
参数:
sock //刚才创建的套接字
msg //要发送的信息
len //发送多少字节的信息
flags //默认设置为0
to //存放对方的ip和端口号
tolen //地址结构体大小 sizeof()
关闭套接字(close)
#include <unistd.h>
int close(int fildes);
参数:
fildes //套接字文件描述符
UDP 接收端解释
由于创建套接字、绑定IP和端口 跟发送端基本一致,所以这里不再贴出代码。可以参考总体代码。
接收信息(recvfrom)
#include <sys/socket.h>
ssize_t recvfrom(int socket,void *buffer,size_t length,int flags, struct sockaddr *address,socklen_t *address_len);
返回值:
参数:
socket //刚才创建的套接字
buffer //保存接收的信息
length //接收多少字节的数据
flags //默认设置为0
address //存放对方的ip和端口号
address_len //地址结构体大小,要求是指针
注意:udp 接收端除了接收信息部分不一样,其余都跟发送端一样。
具体代码
//发送端
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#define N 50
int main(){
int socket;
int ret;
//定义数组保存输入的字符串信息
char buf[N];
//定义ipv4地址结构体变量存放自己ip和端口号
struct sockaddr_in bindaddr;
bindaddr.sin_family = AF_INET;
bindaddr.sin_addr.s_addr = inet_addr("192.168.1.1"); //绑定自己的ip
bindaddr.sin_port = htons(10081); //指定一个通信端口号
//定义ipv4地址结构体变量存放对方的ip和端口号
struct sockadder_in otheraddr;
otheraddr.sin_family = AF_INET;
otheraddr.sin_addr.s_addr = inet_addr("192.168.1.2"); //对方的ip
otheraddr.sin_port = htons(10082); //对方的端口号
//创建套接字
socket = socket(AF_INET, SOCK_DGRAM, 0);
if(socket == -1)
{
printf(" created udp_socket faliure!\n");
}
//绑定ubuntu自己ip和端口号
ret = bind(socket, &bindaddr,sizeof(bindaddr));
if(ret == -1)
{
printf(" bind ip_port faliure! \n");
}
//发送信息给对方-->读取键盘的输入,发送给对方
while(1)
{
printf(" please input the msg: ");
scanf("%s",buf);
sendto(socket, buf, strlen(buf), 0, &otheraddr,sizeof(otheraddr));
}
//关闭套接字
close(socket);
return 0;
}
//udp接收端:
#include <stdio.h>
#include <sys/socket.h>