使用UDP进行通信时,不需要调用accept()
函数。UDP是无连接的协议,这意味着在发送数据之前不需要建立一个稳定的连接。
UDP Socket 的基本流程
- 创建Socket:使用
socket()
函数创建一个UDP类型的Socket,通常指定为SOCK_DGRAM
。 - 绑定(Bind):服务器端将Socket绑定到特定的IP地址和端口,以便接收来自客户端的数据报。
- 接收数据(Receive):服务器通过
recvfrom()
函数接收来自客户端的数据,同时获取发送者的地址信息。 - 发送数据(Send):服务器或客户端可以通过
sendto()
函数向对方发送数据,目标地址在每次发送时都需要明确指定。
示例代码
UDP 服务器代码 (C语言)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#define PORT 8080
#define BUF_SIZE 1024
int main() {
int sockfd;
char buffer[BUF_SIZE];
struct sockaddr_in serv_addr, cli_addr;
socklen_t cli_len = sizeof(cli_addr);
// 创建socket
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
// 定义地址
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(PORT);
// 绑定
if (bind(sockfd, (const struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
perror("bind failed");
exit(EXIT_FAILURE);
}
// 接收数据
while (1) {
int n = recvfrom(sockfd, buffer, BUF_SIZE - 1, MSG_WAITALL,
(struct sockaddr *) &cli_addr, &cli_len);
buffer[n] = '\0'; // Null-terminate the received string
printf("Received: %s\n", buffer);
const char *response = "Hello from server";
sendto(sockfd, response, strlen(response), MSG_CONFIRM,
(const struct sockaddr *) &cli_addr, cli_len);
printf("Response sent.\n");
}
close(sockfd);
return 0;
}
UDP 客户端代码 (C语言)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#define PORT 8080
#define BUF_SIZE 1024
int main() {
int sockfd;
struct sockaddr_in servaddr;
// 创建socket
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
printf("\n Socket creation error \n");
return -1;
}
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(PORT);
// 转换IPv4地址从文本到二进制形式
if(inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr) <= 0) {
printf("\nInvalid address/ Address not supported \n");
return -1;
}
const char *message = "Hello from client";
sendto(sockfd , message , strlen(message) , MSG_CONFIRM ,
(const struct sockaddr *) &servaddr , sizeof(servaddr));
char buffer[BUF_SIZE];
int n;
n = recvfrom(sockfd , buffer , BUF_SIZE - 1 , MSG_WAITALL,
NULL , NULL);
buffer[n] = '\0';
printf("Received: %s\n", buffer);
close(sockfd);
return 0;
}
总结
在UDP中,由于其无连接特性,不需要使用accept()
函数来接受连接请求。相反,双方通过sendto()
和recvfrom()
直接进行消息交换。这使得UDP适合用于实时应用,如视频流和在线游戏,但由于没有重传机制,它也可能导致数据丢失。
内容由零声教学AI助手提供,问题来源于学员提问