《网络编程 — UDP》
1.UDP程序设计框架
跟TCP相比,UDP少了listen、accept、connect。也就是少了三次握手。
所以UDP是无连接的,不可靠的网络协议。
2.recvfrom函数和sendto函数
#include <sys/types.h> #include <sys/socket.h> ssize_t recvfrom(int s, void *buf. size_t len, int flags, struct sockaddr *from, socklen_t *fromlen);
参数:
第一个参数s:表示正在监听的套接字文件描述符。
第二个参数buf:表示接收数据缓冲区。
第三个参数len:表示接收数据缓冲区的大小。系统根据这个值来确保接收缓冲区的安全,防止溢出。
第四个参数from:指向本地的数据结构sockaddr_in的指针,接收数据时发送方的地址信息放在这个结构中。
第五个参数fromlen:表示第四个参数所指内容的长度,可以使用sizeof(struct sockaddr_in)来获得。
返回值:成功的时候返回接收到的数据长度(数据长度可以为0)。失败返回-1,错误值保存在errno中,error的值和含义如下图。
可以通过from中的地址来判断是否要对接收到的数据进行处理。如果不需要判断发送方的地址。可以使用recv()函数是一样的。
#include <sys/types.h> #include <sys/socket.h> ssize_t sendto(int s, const void *buf, size_t len, int flags,
const struct sockaddr *to, socklen_t tolen);
参数:
第一个参数s:正在监听的套接字描述符。
第二个参数buf:发送缓冲区。
第三个参数len:发送数据缓冲区的大小。
第四个参数to:指向目的主机数据结构sockaddr_in的指针,接收数据的主机地址信息放在这个结构中。
第五个参数tolen:表示第四个参数所指内容的长度。
返回值:成功时候返回发送成功的数据长度(数据长度可以为0),失败返回-1。可以查看errno的值
3.UDP简单例程
客户端:
#include <stdio.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #define PROT 7777 #define BUFF_LEN 256 static void udpclient_echo(int sock, struct sockaddr *to); int main(int argc, char *argv[]) { int s; struct sockaddr_in addr_serv; s = socket(AF_INET, SOCK_DGRAM, 0); if(s < 0) { perror("socket"); return 0; } bzero(&addr_serv, sizeof(struct sockaddr_in)); addr_serv.sin_family = AF_INET; addr_serv.sin_addr.s_addr = htonl(INADDR_ANY); addr_serv.sin_port = htons(PROT); udpclient_echo(s, (struct sockaddr *)&addr_serv); close(s); return 0; } static void udpclient_echo(int sock, struct sockaddr *to) { char buff[BUFF_LEN] = "UDP TEST"; sendto(sock, buff, BUFF_LEN, 0, to, sizeof(struct sockaddr)); }
服务器端:
#include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <string.h> #include <netinet/in.h> //sockaddr_in结构体在这个头文件中 #define PORT 7777 #define BUFF_LEN 256 void static udpserv_echo(int s, struct sockaddr *client); int main(int argc, char *argv[]) { int sock; int ret; struct sockaddr_in addr_server, addr_client; sock = socket(AF_INET, SOCK_DGRAM, 0); if(sock < 0) { perror("socket"); return 0; } bzero(&addr_server, sizeof(struct sockaddr_in)); addr_server.sin_family = AF_INET; addr_server.sin_addr.s_addr = htonl(INADDR_ANY); addr_server.sin_port = htons(PORT); ret = bind(sock, (struct sockaddr *)&addr_server, sizeof(struct sockaddr_in)); if(ret < 0) { perror("bind"); return 0; } udpserv_echo(sock, (struct sockaddr *)&addr_client); return 1; } void static udpserv_echo(int sock, struct sockaddr *client) { ssize_t n; char buff[BUFF_LEN]; socklen_t len; while(1) { len = sizeof(*client); n = recvfrom(sock, buff, BUFF_LEN, 0, client, &len); if(n > 0) { printf("server recieve %s,%d bytes\n",buff,len); } } }