网络编程:UDP数据报套接字编程与TCP流套接字编程

目录

一、网络协议的基本概念

二、UDP数据报套接字编程

1.套接字的创建

2.绑定套接字

3.接收与发送数据

三、TCP流套接字编程

1.套接字的创建与绑定

接受连接

数据的接收与发送

关闭连接

四、UDP与TCP的适用场景


网络编程是现代计算机科学和工程领域中一个极为重要的主题。无论是构建分布式系统,还是编写互联网应用程序,网络编程的基本原理都潜移默化地影响着系统的架构、性能和可靠性。在这一领域,套接字(Socket)是实现网络通信的基础,特别是UDP(用户数据报协议)和TCP(传输控制协议)的使用,成为了开发者日常工作中的核心内容。本文将深入探讨UDP数据报套接字和TCP流套接字的编程方法及其各自的特点与应用场景。

一、网络协议的基本概念

在深入讨论套接字编程之前,我们首先需要理解UDP和TCP这两种网络协议之间的区别与联系。UDP是一种无连接的、不可靠的传输协议,允许数据报的快速发送,适用于实时要求高但对数据完整性要求不高的应用场景,例如视频直播和在线游戏。相对而言,TCP是一种面向连接的、可靠的传输协议,确保数据的完整性和顺序,适合对可靠性要求较高的应用,如网页浏览和文件传输。

二、UDP数据报套接字编程

1.套接字的创建

在使用UDP进行网络编程时,我们需要首先创建一个UDP套接字。这通常涉及到指定协议族(一般使用AF_INET表示IPv4),套接字类型(SOCK_DGRAM表示数据报),以及协议(通常为0)。

java 复制代码
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);  
if (sockfd < 0) {  
    perror("socket creation failed");  
    exit(EXIT_FAILURE);  
}  

2.绑定套接字

创建完套接字后,通常需要将其绑定到特定的IP地址和端口号,以便接收数据报。绑定操作示例下述代码所示:

java 复制代码
struct sockaddr_in servaddr;  
memset(&servaddr, 0, sizeof(servaddr));  
servaddr.sin_family = AF_INET;  
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);  
servaddr.sin_port = htons(port);  

if (bind(sockfd, (const struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) {  
    perror("bind failed");  
    exit(EXIT_FAILURE);  
}  

3.接收与发送数据

使用UDP套接字进行数据传输的过程非常直观。发送数据时,我们使用sendto函数;接收数据时,我们使用recvfrom函数。以下是一个简单的发送和接收数据的示例:

java 复制代码
char buffer[1024];  
struct sockaddr_in cliaddr;  
socklen_t len = sizeof(cliaddr);  

// 接收数据

java 复制代码
int n = recvfrom(sockfd, buffer, sizeof(buffer), 0, (struct sockaddr*)&cliaddr, &len);  
buffer[n] = '\0';  
printf("Received: %s\n", buffer);  

// 发送数据

java 复制代码
const char *msg = "Hello from server";  
sendto(sockfd, msg, strlen(msg), 0, (const struct sockaddr*)&cliaddr, len);  

三、TCP流套接字编程

1.套接字的创建与绑定

TCP流套接字的创建步骤与UDP相似,但需要额外注意的是,我们需要使用监听套接字来接受客户端的连接请求。创建和绑定的代码如下:

java 复制代码
int listenfd = socket(AF_INET, SOCK_STREAM, 0);  
if (listenfd < 0) {  
    perror("socket creation failed");  
    exit(EXIT_FAILURE);  
}  

struct sockaddr_in servaddr;  
memset(&servaddr, 0, sizeof(servaddr));  
servaddr.sin_family = AF_INET;  
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);  
servaddr.sin_port = htons(port);  

if (bind(listenfd, (const struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) {  
    perror("bind failed");  
    exit(EXIT_FAILURE);  
}  
// 开始监听  


listen(listenfd, 10);  

接受连接

一旦套接字绑定后,便可以开始接受客户端的连接。使用accept函数可以实现这个过程,它将返回一个新的套接字,用于与特定客户端进行数据交换。

java 复制代码
struct sockaddr_in cliaddr;  
socklen_t len = sizeof(cliaddr);  
int connfd = accept(listenfd, (struct sockaddr*)&cliaddr, &len);  
if (connfd < 0) {  
    perror("server accept failed");  
    exit(EXIT_FAILURE);  
}  

数据的接收与发送

在TCP编程中,数据的发送和接收则依赖于读取和写入流。可以使用recv和send函数进行数据交换。代码如下:

java 复制代码
char buffer[1024];  

// 接收数据  
int n = recv(connfd, buffer, sizeof(buffer), 0);  
buffer[n] = '\0';  
printf("Received: %s\n", buffer);  

// 发送数据  
const char *msg = "Hello from server";  
send(connfd, msg, strlen(msg), 0);  

关闭连接

完成数据交换后,务必关闭套接字以释放资源。以下是关闭套接字的标准方法:

close(connfd);

close(listenfd);

四、UDP与TCP的适用场景

UDP的应用场景:由于其无连接和低延迟,UDP特别适用于实时应用,例如网络游戏、视频会议、语音通话等。在这些场景中,丢失少量数据并不会显著影响用户体验,反而更在乎的是数据能快速到达。

TCP的应用场景:对于需要保证数据完整性和顺序的重要应用,如文件传输、电子邮件、网页浏览等,TCP则是首选协议。其重传机制和流量控制保证了数据的安全传输。

相关推荐
发量惊人的中年网工41 分钟前
工业视觉云边 AI 推理总是卡顿?SD-WAN 打通边缘算力互联
网络·人工智能·网络安全·云计算
AC赳赳老秦1 小时前
软著公开信息批量采集:OpenClaw 抓取软件著作权公开数据,分析企业技术布局方向
大数据·网络·人工智能·python·php·deepseek·openclaw
liuyunshengsir1 小时前
perftest 工具集ib_write_bw中的 RDMA Write 带宽测试工具手册
网络·rdma
tjjingpan1 小时前
HCIP-Datacom Core Technology V1.0_20 IPv6概述
linux·服务器·网络
我命由我123451 小时前
Android 开发 - 广播组件(标准广播、有序广播、静态注册广播、分钟到达广播、网络变更广播...)
android·java·开发语言·网络·java-ee·android studio·android-studio
MartinYeung52 小时前
[论文学习]WASP:面向提示注入攻击的Web代理安全性基准测试
前端·网络·学习
数字融合2 小时前
透明化时空联合无缝追踪,构筑无断点全域态势感知网络专项技术
网络·人工智能·virtualenv
cn分享汇2 小时前
2026免费空间大的网盘软件有哪些推荐,主流网盘拆解
大数据·网络·人工智能
Mr. zhihao2 小时前
Jenkins 从节点连不上主节点?一次网络排查全记录 + 机器间通信“拦截层“全景讲解
网络·servlet·jenkins
数聚天成DeepSData2 小时前
外贸海关进出口数据去哪免费下载?从统计到明细的查找指南
linux·服务器·开发语言·前端·网络·人工智能·自然语言处理