UDP编程模型
1.UDP C/S模型
2.UDP API
socket
int socket(int domain, int type, int protocol);
domain:
AF_INET 这是大多数用来产生socket的协议,使用TCP或UDP来传输,用IPv4的地址
AF_INET6 与上面类似,不过是来用IPv6的地址
AF_UNIX 本地协议,使用在Unix和Linux系统上,一般都是当客户端和服务器在同一台及其上的时候使用
type:
SOCK_STREAM 这个协议是按照顺序的、可靠的、数据完整的基于字节流的连接。这是一个使用最多的socket类型,这个socket是使用TCP来进行传输。
SOCK_DGRAM 这个协议是无连接的、固定长度的传输调用。该协议是不可靠的,使用UDP来进行它的连接。
SOCK_SEQPACKET该协议是双线路的、可靠的连接,发送固定长度的数据包进行传输。必须把这个包完整的接受才能进行读取。
SOCK_RAW socket类型提供单一的网络访问,这个socket类型使用ICMP公共协议。(ping、traceroute使用该协议)
SOCK_RDM 这个类型是很少使用的,在大部分的操作系统上没有实现,它是提供给数据链路层使用,不保证数据包的顺序
protocol:
传0 表示使用默认协议。
返回值:
成功:返回指向新创建的socket的文件描述符,失败:返回-1,设置errno
sendto
int sendto(int sockfd, const void *msg,int len, unsigned int flags, const struct sockaddr *to, int tolen);
to: 表示目地机的IP地址和端口号信息,
tolen: 常常被赋值为sizeof(struct sockaddr)。
sendto 函数也返回实际发送的数据字节长度或在出现发送错误时返回-1。
recvfrom
int recvfrom(int sockfd,void *buf,int len,unsigned int flags,struct sockaddr *from,int *fromlen);
from:是一个struct sockaddr类型的变量,该变量保存源机的IP地址及端口号。
fromlen: 常置为sizeof (struct sockaddr)。
当recvfrom()返回时,fromlen包含实际存入from中的数据字节数。recvfrom()函数返回接收到的字节数或当出现错误时返回-1,并置相应的errno。
3.UDP Server端实现
#include "socket_udp_server.h"
#include "socket_tcp_server.h"
#include "socket_wrap.h"
#include "ctype.h"
static char ReadBuff[BUFF_SIZE];
/**
* @brief udp 服务器任务
* @param None
* @retval None
*/
void vUdpServerTask(void){
int sfd, n, i;
struct sockaddr_in server_addr, client_addr;
socklen_t client_addr_len;
//创建socket udp通信
sfd = Socket(AF_INET, SOCK_DGRAM, 0);
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(SERVER_PORT);
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
//绑定socket
Bind(sfd, (struct sockaddr *)&server_addr, sizeof(server_addr));
client_addr_len = sizeof(client_addr);
while(1){
//等待客户端发送数据
n = Recvfrom(sfd, ReadBuff, BUFF_SIZE, 0, (struct sockaddr *)&client_addr, &client_addr_len);
//进行大小写转换
for(i = 0; i < n; i++){
ReadBuff[i] = toupper(ReadBuff[i]);
}
//写回客户端
Sendto(sfd, ReadBuff, BUFF_SIZE, 0, (struct sockaddr *)&client_addr, client_addr_len);
}
}