dede 网站地图模板htm,北京市建设工程交易中心网站,wordpress 小熊资源网,做牙的网站叫什么一. UDP函数 UDP#xff08;用户数据报协议#xff0c;User Datagram Protocol#xff09;是一种无连接的网络协议#xff0c;用于在互联网上交换数据。它允许应用程序发送数据报给另一端的应用程序#xff0c;但不保证数据报能成功到达#xff0c;也就是说#xff0c;它…一. UDP函数 UDP用户数据报协议User Datagram Protocol是一种无连接的网络协议用于在互联网上交换数据。它允许应用程序发送数据报给另一端的应用程序但不保证数据报能成功到达也就是说它提供的是一种不可靠的服务。与TCP传输控制协议相比UDP的优势在于它的简单性和低开销使得它特别适合于那些对实时性要求高的应用如视频会议和在线游戏。
在编程中使用UDP进行数据通信涉及到一系列的函数调用。这些函数调用通常通过操作系统提供的网络接口与内核进行交互。下面是一些在UDP编程中常用的函数及其与内核的关系
1. socket()
用途创建一个新的套接字socket它是进行网络通信的基础。与内核的关系调用这个函数会让操作系统内核创建一个套接字数据结构并返回一个引用这个结构的文件描述符FD。此后应用程序通过这个文件描述符进行所有网络操作。
2. bind()
用途将套接字与一个特定的IP地址和端口号绑定。对于服务器端应用程序来说这样做可以让它在特定的端口上监听来自客户端的连接或数据。与内核的关系此函数将应用程序指定的IP地址和端口号信息注册到内核中内核会用这些信息来识别到来的数据包是属于哪个应用程序的。
3. sendto()
用途用于向特定的目标地址发送数据。在UDP编程中每次发送数据时都需要指定目的地的地址和端口号。与内核的关系应用程序调用sendto()函数后数据和目标地址信息被传递给内核内核负责将数据打包成UDP数据报并通过网络发送出去。
4. recvfrom()
用途用于接收来自任何地址的数据。应用程序可以通过这个函数获取发送方的地址信息。与内核的关系当UDP数据报到达操作系统时内核会根据数据报的目的端口号找到对应的套接字并将数据放入该套接字的接收缓冲区。应用程序通过recvfrom()函数从这个缓冲区读取数据。
5. close()
用途关闭套接字释放与之相关的资源。与内核的关系调用close()函数后应用程序通知内核它已经完成了对该套接字的使用内核随后会清理与这个套接字相关的资源。
二. TCP编程与UDP编程的区别 连接性 TCP面向连接的协议通信双方需要建立一个稳定的连接然后才能进行数据传输。UDP无连接的协议数据可以直接发送给接收方不需要建立连接。 可靠性 TCP提供可靠的数据传输通过序列号、确认应答、重传机制等确保数据的可靠到达。UDP不保证数据可靠到达可能会出现丢包但UDP在丢包处理上更简单不进行重传。 速度 TCP由于建立连接和保证数据可靠速度相对较慢。UDP因为没有连接建立和数据可靠性检查速度相对较快。 数据流 TCP保证数据的顺序确保应用层接收到的数据顺序与发送顺序一致。UDP不保证数据顺序数据可能会乱序到达。 使用场景 TCP适用于对数据准确性要求较高的场景如文件传输、邮件传输等。UDP适用于对速度要求较高但可以容忍一定程度数据丢失的场景如视频会议、在线游戏等。
三. UDP代码例子
服务器代码
#include stdio.h
#include stdlib.h
#include string.h
#include unistd.h
#include arpa/inet.h
#include sys/socket.h#define PORT 8080
#define BUFFER_SIZE 1024// 函数声明
void error_handling(char *message);int main(int argc, char *argv[]) {int server_socket;struct sockaddr_in server_address, client_address;socklen_t client_address_size sizeof(client_address);char message[BUFFER_SIZE];// 创建UDP套接字server_socket socket(PF_INET, SOCK_DGRAM, 0);if (server_socket -1) {error_handling(socket() error);}// 设置服务器地址结构memset(server_address, 0, sizeof(server_address));server_address.sin_family AF_INET;server_address.sin_addr.s_addr htonl(INADDR_ANY);server_address.sin_port htons(PORT);// 绑定套接字到端口if (bind(server_socket, (struct sockaddr *)server_address, sizeof(server_address)) -1) {error_handling(bind() error);}// 服务器主循环while (1) {// 接收客户端发送的数据int str_len recvfrom(server_socket, message, BUFFER_SIZE, 0, (struct sockaddr *)client_address, client_address_size);if (str_len -1) {error_handling(recvfrom() error);}// 打印接收到的消息printf(Received from client: %s\n, message);// 处理消息这里简单地转换为大写for (int i 0; i str_len; i) {message[i] toupper(message[i]);}// 发送处理后的消息回客户端sendto(server_socket, message, str_len, 0, (struct sockaddr *)client_address, client_address_size);}// 关闭套接字close(server_socket);return 0;
}void error_handling(char *message) {fputs(message, stderr);fputc(\n, stderr);exit(1);
}
客户端代码
#include stdio.h
#include stdlib.h
#include string.h
#include unistd.h
#include arpa/inet.h
#include sys/socket.h#define PORT 8080
#define BUFFER_SIZE 1024// 函数声明
void error_handling(char *message);int main(int argc, char *argv[]) {int client_socket;struct sockaddr_in server_address;char message[BUFFER_SIZE];int message_len;// 创建UDP套接字client_socket socket(PF_INET, SOCK_DGRAM, 0);if (client_socket -1) {error_handling(socket() error);}// 设置服务器地址结构memset(server_address, 0, sizeof(server_address));server_address.sin_family AF_INET;server_address.sin_addr.s_addr inet_addr(127.0.0.1);server_address.sin_port htons(PORT);// 循环读取用户输入并发送给服务器while (1) {printf(Input message(Q to quit): );fgets(message, BUFFER_SIZE, stdin);// 检查是否退出if (!strcmp(message, q\n) || !strcmp(message, Q\n)) {break;}// 发送消息给服务器sendto(client_socket, message, strlen(message), 0, (struct sockaddr *)server_address, sizeof(server_address));// 接收服务器响应message_len recvfrom(client_socket, message, BUFFER_SIZE, 0, NULL, 0);if (message_len -1) {error_handling(recvfrom() error);}// 打印服务器响应message[message_len] 0;printf(Message from server: %s\n, message);}// 关闭套接字close(client_socket);return 0;
}void error_handling(char *message) {fputs(message, stderr);fputc(\n, stderr);exit(1);
}