知识地图

1.UDP通信基本流程

图 1
2.示例程序
2.1 服务端程序
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/uio.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define MAX_BUF_LEN (1500)
#define ACK_STR "udp ack ok"
void usage(void) {
printf("*********************************\n");
printf("./server 本端ip 本端端口\n");
printf("*********************************\n");
}
int main(int argc, char *argv[]) {
int sockfd;
int ret;
ssize_t len = 0;
struct sockaddr_in local;
struct sockaddr_in peer;
socklen_t addrlen = sizeof(peer);
char recv_buf[MAX_BUF_LEN] = {0};
if (argc != 3) {
usage();
return -1;
}
char *ip = argv[1];
unsigned short port = atoi(argv[2]);
printf("ip:port->%s:%u\n", argv[1], port);
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd == -1) {
perror("socker error");
return -1;
}
memset(&local, 0, sizeof(local));
local.sin_family = AF_INET;
local.sin_addr.s_addr = inet_addr(ip);
local.sin_port = htons(port);
ret = bind(sockfd, (struct sockaddr *)&local, sizeof(local));
if (ret == -1) {
close(sockfd);
perror("bind error");
return -1;
}
while(1) {
memset(recv_buf, 0, MAX_BUF_LEN);
ret = recvfrom(sockfd, recv_buf, MAX_BUF_LEN, 0,
(struct sockaddr *)&peer, &addrlen);
printf("recvfrom peer len:%d, peer ip:port->%s:%d\n",
addrlen,
inet_ntoa(peer.sin_addr),
ntohs(peer.sin_port));
printf("recvfrom len:%d, %s\n", ret, recv_buf);
ret = sendto(sockfd, ACK_STR, strlen(ACK_STR), 0,
(struct sockaddr *)&peer, sizeof(peer));
printf("sendto len:%d, %s\n", ret, ACK_STR);
}
close(sockfd);
return 0;
}
2.2 客户端程序
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <bits/socket.h>
#include <sys/uio.h>
#define MAX_BUF_LEN (1500)
#define REQUEST_STR "udp pack"
void usage(void) {
printf("*********************************\n");
printf("./client 对端ip 对端端口\n");
printf("*********************************\n");
}
int main(int argc, char *argv[]) {
int sockfd;
int ret;
struct sockaddr_in local;
struct sockaddr_in peer;
socklen_t addrlen = sizeof(peer);
char recv_buf[MAX_BUF_LEN] = {0};
if (argc != 3) {
usage();
return -1;
}
char *ip = argv[1];
unsigned short port = atoi(argv[2]);
printf("ip:port->%s:%u\n", argv[1], port);
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd == -1) {
perror("socker error");
return -1;
}
memset(&peer, 0, sizeof(peer));
peer.sin_family = AF_INET;
peer.sin_addr.s_addr = inet_addr(ip);
peer.sin_port = htons(port);
while(1) {
ret = sendto(sockfd, REQUEST_STR, strlen(REQUEST_STR), 0,
(struct sockaddr *)&peer, sizeof(peer));
printf("sendto len:%d, %s\n", ret, REQUEST_STR);
memset(recv_buf, 0, MAX_BUF_LEN);
ret = recvfrom(sockfd, recv_buf, MAX_BUF_LEN, 0,
(struct sockaddr *)&peer, &addrlen);
printf("recvfrom peer len:%d, peer ip:port->%s:%d\n",
addrlen,
inet_ntoa(peer.sin_addr),
ntohs(peer.sin_port));
printf("recvfrom len:%d, %s\n", ret, recv_buf);
sleep(1);
}
close(sockfd);
return 0;
}
3.调试
3.1 编译
服务端命令 #gcc server.c -o server
客户端命令 #gcc client.c -o client
3.2 运行
服务端命令 #./server 本端ip 本端端口
客户端命令 #./client 对端ip 对端端口
输出结果:
服务端打印:

客户端打印:

