Question: How to use UDP to send and receive data?
On UDP Protocol Again
- UDP is connectionless ( unreliable, no reply messages, no sequence number identification of packets )
- UDP is packet-oriented,
对应用层数据既不合并也不拆分
(packet boundaries are preserved) - UDP has no congestion control, network congestion will not reduce the sending rate of the source host
- UDP supports one-to-one, one-to-many, many-to-one and many-to-many interactive communication
- UDP message header overhead is small, only 8 bytes (TCP message header has a total of 20 bytes)
Difference between UDP and IP
UDP is a data transfer protocol built on top of IP
- IP is responsible for transferring UDP packets from source host to destination host
- UDP delivers application layer data to the target socket (port number)
UDP almost completely "inherits" the characteristics of IP transmission
- There is no interaction between the two ends of the communication, no flow control, no timeout retransmission, and no reliability.
UDP send and receive data
#include "sys/socket.h"
ssize_t send(int sock, // socket 文件描述符
void *buf, // 需要发送的数据
size_t nbytes, // 需要发送的数据量
int flags, // 发送选项
struct sockaddr *to, // 接收地址信息
socklen_t addrlen); // to 参数长度
ssize_t recvfrom(int sock, // socket 文件描述符
void *buf, // 保存接收数据的地址
size_t nbytes, // 可接收的最大数据量
int flags, // 接收选项
struct sockaddr *from, // 接收地址信息
socklen_t *addrlen); // 指向保存 from 参数长度的变量地址
UDP programming mode
Programming experiment: UDP data transmission and reception
client.c
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main()
{
int sock = 0;
struct sockaddr_in addr = {0};
struct sockaddr_in remote = {0};
socklen_t len = 0;
char buf[128] = {0};
char input[32] = {0};
int r = 0;
sock = socket(PF_INET, SOCK_DGRAM, 0);
if (sock == -1) {
printf("socket error\n");
return -1;
}
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(7777);
if (bind(sock, (struct sockaddr*)&addr, sizeof(addr)) == -1) { // 特别说明, 当使用 udp socket 进行数据发送时,不指定 bind (即,ip 和 port) 也能将数据成功发送
printf("udp bind error\n"); // 但 udp 是无连接的,因此不像 TCP 有非常明显的服务端等待客户端发起连接的过程
return -1; // udp 的通信端点是对等的,为了方便接收其他端点发送的数据,因此指定了 ip 和 端口号 (尤其端口号)
}
remote.sin_family = AF_INET;
remote.sin_addr.s_addr = inet_addr("127.0.0.1");
remote.sin_port = htons(8888);
while (1) {
printf("Input: ");
scanf("%s", input);
len = sizeof(remote);
sendto(sock, input, strlen(input), 0, (struct sockaddr*)&remote, len);
r = recvfrom(sock, buf, sizeof(buf), 0, (struct sockaddr*)&remote, &len);
if (r > 0) {
buf[r] = 0;
printf("Recvfrom %s\n", buf);
} else {
break;
}
}
close(sock);
return 0;
}
server.c
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main()
{
int server = 0;
struct sockaddr_in saddr = {0};
int client = 0;
struct sockaddr_in remote = {0};
socklen_t asize = 0;
int len = 0;
char buf[32] = {0};
int r = 0;
server = socket(PF_INET, SOCK_DGRAM, 0);
if (server == -1) {
printf("server socket error");
return -1;
}
saddr.sin_family = AF_INET;
saddr.sin_addr.s_addr = htonl(INADDR_ANY);
saddr.sin_port = htons(8888);
if (bind(server, (struct sockaddr*)&saddr, sizeof(saddr)) == -1) {
printf("udp server bind error\n");
return -1;
}
printf("udp server start sucess\n");
while (1) {
len = sizeof(remote);
r = recvfrom(server, buf, sizeof(buf), 0, (struct sockaddr*)&remote, &len);
buf[r] = 0;
printf("r = %d\n", r);
printf("buf = %s\n", buf);
printf("remote ip = %s\n", inet_ntoa(remote.sin_addr));
printf("remote port = %d\n", ntohs(remote.sin_port));
sendto(server, buf, r, 0, (struct sockaddr*)&remote, len);
}
close(server);
return 0;
}
output:
server:
udp server start sucess
r = 5
buf = hello
remote ip = 127.0.0.1
remote port = 7777
---
client:
Input: hello
Recvfrom hello
Thinking: How to send and receive UDP data one-to-many?
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。