如何进行网络通信和套接字编程?

网络通信和套接字编程

引言

网络通信是计算机科学中的重要概念,它使得不同计算机之间可以进行数据交换和信息传递。套接字编程是一种实现网络通信的方法,它提供了一套标准的接口,使得应用程序可以通过网络进行数据传输。本文将详细介绍网络通信的基本原理、套接字编程的概念,以及使用C语言进行套接字编程的基本步骤。

网络通信基本原理

在计算机网络中,通信的基本单元是数据包(Packet)。数据包是一种数据的封装形式,它包含了要传输的信息以及相关的控制信息。在网络中,数据包通过不同的协议进行传输,常见的网络协议包括TCP(Transmission Control Protocol)和UDP(User Datagram Protocol)等。

TCP(Transmission Control Protocol)

TCP是一种面向连接的、可靠的协议。它确保数据的可靠传输,通过三次握手建立连接,保持连接状态,最后通过四次挥手终止连接。TCP提供流式传输,数据被分割成小的数据块,通过序列号和确认应答机制来保证数据的完整性和顺序性。

UDP(User Datagram Protocol)

UDP是一种无连接的、不可靠的协议。它不进行连接的建立和维护,也不提供数据的可靠传输,数据包可能会丢失或乱序。UDP适用于一些对传输延迟要求较低、对数据可靠性要求较低的场景。

套接字编程概念

套接字(Socket)是一种通信机制,它允许不同计算机上的进程通过网络进行通信。套接字提供了一组接口,使得应用程序可以创建、连接、传输数据以及关闭连接。

在套接字编程中,常见的两种类型是流套接字(Stream Socket)和数据报套接字(Datagram Socket)。流套接字基于TCP协议,提供面向连接的通信,而数据报套接字基于UDP协议,提供无连接的通信。

C语言套接字编程基本步骤

套接字编程通常涉及以下基本步骤:

步骤一:创建套接字

在C语言中,可以使用socket函数来创建一个套接字。socket函数的原型如下:

#include <sys/types.h>
#include <sys/socket.h>int socket(int domain, int type, int protocol);
  • domain参数指定了通信协议的地址族,常用的有AF_INET(IPv4)和AF_INET6(IPv6)。
  • type参数指定了套接字的类型,常用的有SOCK_STREAM(流套接字,对应TCP)和SOCK_DGRAM(数据报套接字,对应UDP)。
  • protocol参数指定了使用的协议,通常为0,表示使用默认协议。

例如,创建一个TCP套接字:

#include <sys/types.h>
#include <sys/socket.h>int main() {int sockfd = socket(AF_INET, SOCK_STREAM, 0);if (sockfd == -1) {perror("Error creating socket");return 1;}// 其他操作...return 0;
}

步骤二:绑定套接字

在创建套接字后,通常需要将套接字与一个具体的地址和端口进行绑定。使用bind函数来完成这一步骤。

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
  • sockfd参数是socket函数返回的套接字描述符。
  • addr参数是一个指向sockaddr结构的指针,用于指定地址和端口。
  • addrlen参数表示addr结构的大小。

例如,将套接字绑定到本地地址和端口:

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>int main() {int sockfd = socket(AF_INET, SOCK_STREAM, 0);if (sockfd == -1) {perror("Error creating socket");return 1;}struct sockaddr_in server_addr;server_addr.sin_family = AF_INET;server_addr.sin_port = htons(8080); // 端口号server_addr.sin_addr.s_addr = INADDR_ANY; // 任意本地地址if (bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {perror("Error binding socket");return 1;}// 其他操作...return 0;
}

步骤三:监听连接

对于TCP套接字,需要调用listen函数开始监听连接。

#include <sys/types.h>
#include <sys/socket.h>int listen(int sockfd, int backlog);
  • sockfd参数是socket函数返回的套接字描述符。
  • backlog参数指定了待处理连接的队列长度。
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>int main() {int sockfd = socket(AF_INET, SOCK_STREAM, 0);if (sockfd == -1) {perror("Error creating socket");return 1;}struct sockaddr_in server_addr;server_addr.sin_family = AF_INET;server_addr.sin_port = htons(8080); // 端口号server_addr.sin_addr.s_addr = INADDR_ANY; // 任意本地地址if (bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {perror("Error binding socket");return 1;}if (listen(sockfd, 5) == -1) { // 允许最多5个等待连接的客户端perror("Error listening on socket");return 1;}// 其他操作...return 0;
}

步骤四:接受连接

对于TCP套接字,使用accept函数来接受连接。

#include <sys/types.h>
#include <sys/socket.h>int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
  • sockfd参数是socket函数返回的套接字描述符。
  • addr参数是一个指向sockaddr结构的指针,用于存储连接方的地址信息。
  • addrlen参数表示addr结构的大小。
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>int main() {int sockfd = socket(AF_INET, SOCK_STREAM, 0);if (sockfd == -1) {perror("Error creating socket");return 1;}struct sockaddr_in server_addr;server_addr.sin_family = AF_INET;server_addr.sin_port = htons(8080); // 端口号server_addr.sin_addr.s_addr = INADDR_ANY; // 任意本地地址if (bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {perror("Error binding socket");return 1;}if (listen(sockfd, 5) == -1) { // 允许最多5个等待连接的客户端perror("Error listening on socket");return 1;}struct sockaddr_in client_addr;socklen_t client_addrlen = sizeof(client_addr);int newsockfd = accept(sockfd, (struct sockaddr *)&client_addr, &client_addrlen);if (newsockfd == -1) {perror("Error accepting connection");return 1;}// 其他操作...return 0;
}

步骤五:连接到服务器

对于TCP套接字,客户端需要使用connect函数连接到服务器。

#include <sys/types.h>
#include <sys/socket.h>int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
  • sockfd参数是socket函数返回的套接字描述符。
  • addr参数是一个指向sockaddr结构的指针,用于指定服务器的地址和端口。
  • addrlen参数表示addr结构的大小。
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>int main() {int sockfd = socket(AF_INET, SOCK_STREAM, 0);if (sockfd == -1) {perror("Error creating socket");return 1;}struct sockaddr_in server_addr;server_addr.sin_family = AF_INET;server_addr.sin_port = htons(8080); // 服务器端口号server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); // 服务器地址if (connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {perror("Error connecting to server");return 1;}// 其他操作...return 0;
}

步骤六:发送和接收数据

使用sendrecv函数来发送和接收数据。

#include <sys/types.h>
#include <sys/socket.h>ssize_t send(int sockfd, const void *buf, size_t len, int flags);
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
  • sockfd参数是socket函数返回的套接字描述符。
  • buf参数是一个指向要发送或接收数据的缓冲区。
  • len参数表示要发送或接收的数据的大小。
  • flags参数通常为0,表示没有特殊操作。
#include <sys/types.h>
#include <sys/socket.h>int main() {int sockfd = socket(AF_INET, SOCK_STREAM, 0);if (sockfd == -1) {perror("Error creating socket");return 1;}struct sockaddr_in server_addr;server_addr.sin_family = AF_INET;server_addr.sin_port = htons(8080); // 服务器端口号server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); // 服务器地址if (connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {perror("Error connecting to server");return 1;}char message[] = "Hello, Server!";if (send(sockfd, message, sizeof(message), 0) == -1) {perror("Error sending message");return 1;}char buffer[1024];if (recv(sockfd, buffer, sizeof(buffer), 0) == -1) {perror("Error receiving message");return 1;}printf("Received message from server: %s\n", buffer);// 其他操作...return 0;
}

步骤七:关闭套接字

在通信结束后,需要使用close函数关闭套接字。

#include <unistd.h>int close(int sockfd);

sockfd参数是socket函数返回的套接字描述符。

#include <sys/types.h>
#include <sys/socket.h>int main() {int sockfd = socket(AF_INET, SOCK_STREAM, 0);if (sockfd == -1) {perror("Error creating socket");return 1;}struct sockaddr_in server_addr;server_addr.sin_family = AF_INET;server_addr.sin_port = htons(8080); // 服务器端口号server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); // 服务器地址if (connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {perror("Error connecting to server");return 1;}// 发送和接收数据...if (close(sockfd) == -1) {perror("Error closing socket");

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/162095.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python---global关键字---设置全局变量

global 英 /ˈɡləʊb(ə)l/ adj. 全球的&#xff0c;全世界的&#xff1b;全面的&#xff0c;整体的&#xff1b;&#xff08;计算机&#xff09;全局的&#xff1b;球形的 需求&#xff1a;如果有一个数据&#xff0c;在函数A和函数B中都要使用&#xff0c;该怎么办&…

【PyGIS】使用阿里AIEarth快速下载指定区域指定年份的土地利用数据

说明 中国逐年土地覆盖数据集(CLCD) 由武汉大学的杨杰和黄昕教授团队基于Landsat影像制作了中国逐年土地覆盖数据集(annual China Land Cover Dataset, CLCD),数据包含1985—2021年中国逐年土地覆盖信息。研究团队基于Landsat长时序卫星观测数据,构建时空特征,结合随机森…

Linux常用命令——blockdev命令

在线Linux命令查询工具 blockdev 从命令行调用区块设备控制程序 补充说明 blockdev命令在命令调用“ioxtls”函数&#xff0c;以实现对设备的控制。 语法 blockdev(选项)(参数)选项 -V&#xff1a;打印版本号并退出&#xff1b; -q&#xff1a;安静模式&#xff1b; -v&…

蓝桥杯官网填空题(重合次数)

问题描述 在同一天中, 从上午 6 点 13 分 22 秒到下午 14 点 36 分 20 秒, 钟表上的 分针和秒针一共重合了多少次? 注意时针、分针、秒针都围绕中心敳匀速运动。 答案提交 这是一道结果填空的题&#xff0c;你只需要算出结果后提交即可。本题的结果为一 个整数, 在提交答案…

【正则插件】前端正则插件以及预览插件推荐

1&#xff09; 2&#xff09; any-rule Pegex Previewer 下载好插件之后 在代码层右键选择 选择你需要的正则表达式&#xff0c;随后可以使用第二个插件 正则表达式插入之后顶部会有 Test Regex.. 点击会出现以下内容 将他 ctrl a 删除&#xff0c;输入你对应的正则表达…

@Validated注解的作用代码示例

当使用Spring框架进行参数验证时&#xff0c;可以通过Validated注解来触发参数验证。以下是一个简单的示例&#xff0c;演示了如何在Spring控制器中使用Validated注解来验证请求的参数&#xff1a; 首先&#xff0c;假设有一个简单的User类作为请求的数据模型&#xff1a; pu…

电脑序列号查询

电脑序列号是厂商给每台电脑分配的一个产品识别码&#xff0c;也称为S/N&#xff08;Serial Number&#xff09;。主要用来查询电脑的出厂日期、保修状态、生产产地、产品配置等信息。电脑序列号查询有以下几种方法&#xff1a; 1、电脑机箱外壳&#xff1b; 2、系统信息/命令…

前端下载文件链接

前端下载文件链接 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title> </hea…

CSS 文字溢出:ellipsis在IE上不起效果

单行文本的溢出显示省略号 p {overflow: hidden;text-overflow: ellipsis;white-space: nowrap; }多行文本的溢出显示省略号 方法一&#xff1a; p {display: -webkit-box;-webkit-box-orient: vertical;-webkit-line-clamp: 3;overflow: hidden;text-overflow: ellipsis; }…

梁培强:塑造下一代投资高手

在当前全球经济动荡和金融市场快速变化的背景下&#xff0c;梁培强的投资教育计划不仅仅是一套课程&#xff0c;它是对传统投资理念的深度挑战和革新。梁培强&#xff0c;拥有超过二十年金融行业经验的资深分析师&#xff0c;正在引领一场投资者教育的变革&#xff0c;旨在培养…

C++中的Makefile是什么, 如何使用

Makefile简介 Makefile是一种用于构建C/C程序的文件&#xff0c;其中包含了项目中所有源文件、头文件以及编译器和链接器指令。使用Makefile可以使编译和链接成为一个自动化的过程&#xff0c;这样就可以方便地管理复杂的项目。 以下是一个简单的Makefile示例&#xff1a; C…

Centos 7 安装yum(针对python卸载yum出错)

提前下载所需安装包&#xff0c;按照下面顺序安装即可完成&#xff0c;每个依赖包必须正确安装 下载地址&#xff1a;http://mirrors.163.com/centos/7/os/x86_64/Packages/ rpm -qa|grep python|xargs rpm -ev --allmatches --nodeps ##强制删除已安装程序及其关联 whereis …

基于SSM+Vue的社区共享食堂管理系统

基于SSM的社区共享食堂管理系统的设计与实现~ 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringMyBatisSpringMVC工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 主页 菜品详情 管理员界面 摘要 社区共享食堂管理系统是一种基于SSM&#xf…

CentOS 7实现类似于Kali Linux中的自动补全功能

在CentOS 7中&#xff0c;可以通过安装和使用Bash-completion来实现自动补全功能&#xff0c;类似于Kali Linux中的自动补全。以下是安装和使用Bash-completion的步骤&#xff1a; 首先&#xff0c;确保您的系统已更新并安装了EPEL存储库。&#xff08;非必要&#xff0c;直接…

实现数据全字段搜索

代码 按钮 <el-button type"text" style"position: absolute;top:-48px;right:260px;z-index: 99;color: #000;"click"handleButtonClick(搜索), showConfirmationModal2()" :class"{ blue-text: activeButton 搜索 }"><im…

二、sql手工注入

一、SQL注入的本质 解释&#xff1a;想要进行sql注入&#xff0c;肯定要发现注入点&#xff0c;一般简单的sql注入通过下面两种方式判断就能发现是否存在sql注入漏洞 1.字符型 注意&#xff1a;字符型注入可能为或" 查询语句&#xff1a; select * from student where…

Python生成exe文件

Python如何生成exe文件 在终端执行 pip install pyinstaller 在终端执行pyinstaller E:\fund_data\GetFund.py&#xff0c;运行结束后会在D:\Python\Python311\Scripts\dist\目录下生成GetFund.exe文件 3.双击exe文件运行&#xff0c;如果未出现预期结果&#xff0c;可以把e…

含分布式电源的配电网可靠性评估(matlab代码)

1主要内容 该程序参考《基于仿射最小路法的含分布式电源配电网可靠性分析》文献方法&#xff0c;通过概率模型和时序模型分别进行建模&#xff0c;实现基于概率模型最小路法的含分布式电源配电网可靠性评估以及时序模型序贯蒙特卡洛模拟法的含分布式电源配电网可靠性评估。程序…

区间第k小数 (可持久化线段树、主席树)

题意&#xff1a;多次询问&#xff0c;每次询问某区间的第k小数。 可持久化线段树&#xff1a; 掺杂了一点前缀和的思想&#xff0c;对于每一个1 ~ i 的区间都建一个树&#xff0c;每个节点存的都是一个线段树&#xff0c;值存的是当前区间中初始数组按大小排序后[l, r]之间的…

【AGC】鸿蒙应用软件包上传问题解析

【问题背景】 近期收到了一些反馈&#xff0c;一些鸿蒙元服务开发者在发布应用市场的过程中&#xff0c;上传.app包时遇到了不同的报错&#xff0c;导致上传失败&#xff0c;下面来看一下这些报错的具体原因&#xff0c;如何正确打包上传。 【问题描述1】 HarmonyOS元服务软件…