面试问题--Linux网络编程

Linux网络编程涉及在Linux操作系统上使用套接字(socket)等工具进行网络通信。以下是一些与Linux网络编程相关的主题:

  1. 套接字编程: 在Linux中,套接字是网络编程的基础。可以使用C语言中的socket库来创建套接字。套接字可用于实现各种网络通信协议,包括TCP和UDP。
#include <sys/socket.h>
  1. IP地址和端口: 在网络编程中,需要理解IP地址和端口的概念。IP地址用于标识网络上的计算机,而端口用于标识一个应用程序。

  2. TCP编程: 使用TCP协议进行网络通信的示例,包括创建服务器和客户端程序,建立连接,发送和接收数据等。

  3. UDP编程: 使用UDP协议进行无连接的网络通信的示例。UDP适用于一些实时性要求较高,可以容忍少量数据丢失的场景。

  4. 多路复用(Multiplexing): Linux提供了一些系统调用,如select、poll、epoll等,用于实现多路复用,允许一个进程同时监视多个文件描述符的可读和可写状态。

  5. 线程和进程: 可以使用线程和进程来实现并发的网络编程。在Linux中,可以使用pthread库来进行线程编程,而进程可以通过fork系统调用创建。

#include <pthread.h>
  1. 网络调试工具: 在Linux上有一些用于网络调试的工具,如tcpdump、wireshark等,它们可以帮助分析网络数据包和排查网络问题。

  2. 网络安全: 网络编程中需要考虑安全性,例如使用SSL/TLS协议来加密通信,防止中间人攻击。
    套接字(Socket)是网络编程中的基础概念,用于在不同计算机之间进行通信。套接字提供了一种统一的接口,使得不同计算机上的应用程序能够通过网络进行数据交换。以下是套接字的概念和基本使用方法:

套接字的概念:

套接字类型: 有两种主要的套接字类型,分别是流套接字(SOCK_STREAM)和数据报套接字(SOCK_DGRAM)。

  • 流套接字(TCP): 提供面向连接的、可靠的、双向的数据流。使用socket()函数创建。
  • 数据报套接字(UDP): 提供无连接的、不可靠的数据报传输。同样使用socket()函数创建。
  • 套接字地址: 在网络中,套接字由IP地址和端口号唯一标识。套接字地址结构通常为struct sockaddr,而在实际使用中,可能会使用更具体的结构,如struct sockaddr_in。

1. 创建套接字:

在C语言中,可以使用socket()函数创建套接字。示例:

#include <sys/socket.h>
int socket(int domain, int type, int protocol);

domain: 地址族,通常使用AF_INET表示IPv4。
type: 套接字类型,可以是SOCK_STREAM(TCP)或SOCK_DGRAM(UDP)。
protocol: 使用的协议,一般设置为0,系统会根据类型自动选择合适的协议。

2. 绑定套接字:

在服务器端,需要将套接字与一个特定的IP地址和端口号绑定在一起。可以使用bind()函数:

#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

sockfd: 套接字描述符,由socket()函数返回。
addr: 指向struct sockaddr的指针,包含要绑定的地址信息。
addrlen: 地址结构的长度。

3. 监听连接(仅适用于TCP):

对于使用TCP的服务器,需要监听连接请求。可以使用listen()函数:

#include <sys/socket.h>
int listen(int sockfd, int backlog);

sockfd: 套接字描述符,通过socket()和bind()创建。
backlog: 等待连接队列的最大长度。

4. 接受连接请求(仅适用于TCP):

使用accept()函数接受客户端的连接请求:


#include <sys/socket.h>
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

sockfd: 服务器套接字描述符,通过socket()和bind()创建,并通过listen()设置为监听状态。
addr: 用于存放客户端地址信息的结构体指针。
addrlen: 指向存放地址结构体长度的变量的指针。

5. 连接到服务器(仅适用于TCP):

在客户端,使用connect()函数连接到服务器:

#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

sockfd: 客户端套接字描述符,通过socket()创建。
addr: 服务器地址信息结构体指针。
addrlen: 地址结构体的长度。

6. 发送和接收数据:

使用send()和recv()函数(或者write()和read())在套接字之间传输数据:

#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: 套接字描述符。
buf: 缓冲区指针,用于存放发送或接收的数据。
len: 数据长度。
flags: 控制发送和接收的方式。

使用UDP(User Datagram Protocol)进行网络通信相对简单,因为它是一种无连接的、不可靠的传输协议。以下是使用UDP的基本步骤,包括创建UDP套接字、绑定套接字、发送和接收数据:

1. 创建UDP套接字:

在C语言中,可以使用socket()函数创建UDP套接字。指定套接字类型为SOCK_DGRAM:

#include <sys/socket.h>int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd == -1) {perror("Error creating socket");// 处理错误
}

2. 绑定套接字:

在服务器端,通常需要将UDP套接字绑定到一个特定的端口上。这可以使用bind()函数来完成:

#include <sys/socket.h>
#include <netinet/in.h>struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;
server_addr.sin_port = htons(12345);if (bind(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1) {perror("Error binding socket");// 处理错误
}

3. 发送数据:

使用sendto()函数发送UDP数据。不需要提前建立连接,直接将数据发送到目标地址:

#include <unistd.h>struct sockaddr_in client_addr;
client_addr.sin_family = AF_INET;
client_addr.sin_addr.s_addr = inet_addr("127.0.0.1");  // 目标IP地址
client_addr.sin_port = htons(54321);  // 目标端口号const char *message = "Hello, UDP!";
if (sendto(sockfd, message, strlen(message), 0, (struct sockaddr*)&client_addr, sizeof(client_addr)) == -1) {perror("Error sending data");// 处理错误
}

4. 接收数据:

使用recvfrom()函数接收UDP数据。从任意发送方接收数据,返回发送方的地址信息:

char buffer[1024];
struct sockaddr_in sender_addr;
socklen_t sender_len = sizeof(sender_addr);ssize_t bytes_received = recvfrom(sockfd, buffer, sizeof(buffer), 0, (struct sockaddr*)&sender_addr, &sender_len);
if (bytes_received == -1) {perror("Error receiving data");// 处理错误
} else {buffer[bytes_received] = '\0';  // 在接收到的数据末尾添加 null 终止符printf("Received data from %s:%d: %s\n", inet_ntoa(sender_addr.sin_addr), ntohs(sender_addr.sin_port), buffer);
}

5. 关闭套接字:

在程序结束时,记得关闭UDP套接字:

close(sockfd);

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

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

相关文章

【人工智能Ⅰ】实验3:蚁群算法

实验3 蚁群算法的应用 一、实验内容 TSP 问题的蚁群算法实现。 二、实验目的 1. 熟悉和掌握蚁群算法的基本概念和思想&#xff1b; 2. 理解和掌握蚁群算法的参数选取&#xff0c;解决实际应用问题。 三、实验原理 1&#xff0e;算法来源 蚁群算法的基本原理来源于自然界…

C++学习 --谓词

目录 1&#xff0c; 什么是谓词 1-1&#xff0c; 一元谓词 1-2&#xff0c; 二元谓词 1&#xff0c; 什么是谓词 返回bool类型的仿函数&#xff0c; 叫着谓词&#xff0c; 分为一元谓词和二元谓词 1-1&#xff0c; 一元谓词 operator()接收一个参数&#xff0c;叫着一元谓…

python第1天之常识及环境安装

前言&#xff1a; 当谈到编程语言的流行度时&#xff0c;Python绝对是其中之一。Python是一种高级编程语言&#xff0c;其语法简单易懂&#xff0c;适用于各种不同的应用领域&#xff0c;包括Web开发、数据分析、人工智能等。在本文中&#xff0c;我们将探讨一些关于Pyth…

【JavaScript】3.2 JavaScript性能优化

文章目录 1. 避免全局查找2. 避免不必要的属性查找3. 使用快速的JavaScript方法4. 避免不必要的DOM操作5. 使用Web Workers进行后台处理总结 性能优化是任何编程语言的重要组成部分&#xff0c;JavaScript也不例外。在这个章节中&#xff0c;我们将探讨如何优化JavaScript代码&…

GAN:WGAN

论文&#xff1a;https://arxiv.org/pdf/1701.07875.pdf 发表&#xff1a;2017 WGAN 算法流程 从GAN 到 WGAN 的转变 相比于原始 GAN&#xff0c;WGAN 只需要修改以下几点&#xff0c;就能使得训练更稳定&#xff0c;生成质量更高&#xff1a; 1. 此时的判别器相当于做回归…

【DDD】领域驱动设计总结——如何构造领域模型

文章目录 一 分离领域二 领域对象分类2.1 实体(ENTITY)2.2 值对象(VALUE OBJECT)2.3 服务(SERVICE)2.4 模块&#xff08;&#xff2d;ODULE&#xff09; 三 管理领域对象的生命周期3.1 聚合&#xff08;AGGREGATE&#xff09;3.2 工厂&#xff08;FACTORY&#xff09;3.3 存储库…

记i18n ally工具检测语言失败的一则思路

情况 只有某个文件检测不到汉字&#xff0c;其余都可以检测出来&#xff0c;困扰许久&#xff0c;发个博客记一下思路 解决方法&#xff1a; 1、肯定不是i18n ally工具的问题&#xff0c;因为其他的vue都能检测成功 2、是这个文件的问题 采用排除法 先删掉所有代码&#…

《Effective C++》条款27

尽量少做转型动作 class A { public:A(int x) :a(x) {};virtual void add(){a;} private:int a; }; class B :public A { public:B(int x) :b(x),A(x) {};virtual void add(){static_cast<A>(*this).add();b;}private:int b; }; 如上描述把子类转型为A类&#xff0c;调用…

解决keil右键Go To Definition跳转不过去的问题

解决&#xff1a; 在魔法棒中如图所示打上√

rabbitmq技术

1&#xff0c;docker运行rabbitmq docker run --restartalways -d --hostname my-rabbit --name rabbit -p 15672:15672 -p 5672:5672 rabbitmq 2&#xff0c;新增管理员用户 rabbitmq服务&#xff0c;添加用户以及授权_rabbitmq添加用户授权_ROBOT玲玉的博客-CSDN博客

flask web开发学习之初识flask(二)

文章目录 一、创建程序实例并注册路由1. 为视图绑定绑定多个URL2. 动态URL 二、启动开发服务器1. 自动发现程序实例2. 管理环境变量3. 使用pycharm运行服务器4. 更多的启动选项5. 设置运行环境6. 调试器7. 重载器 一、创建程序实例并注册路由 app.py # 从flask包中导入flask类…

NoSQL 数据建模错误会降低性能

数据建模错误是破坏性能的最简单方法之一。当您使用 NoSQL 时&#xff0c;特别容易搞砸&#xff0c;&#xff08;讽刺的是&#xff09;NoSQL 往往用于对性能最敏感的工作负载。NoSQL 数据建模最初可能看起来非常简单&#xff1a;只需对数据进行建模以适应应用程序的访问模式。但…

Elastic Search

ElasticSearch 持续更新中… 选择es的原因 在数据量非常大的时候&#xff0c;业务进行模糊查询会导致索引失效&#xff0c;查询效率低下&#xff0c;使用es进行查询&#xff0c;可以提高查询速度。 text和keyword类型的区别 keyword 类型是不会分词的&#xff0c;直接根据字…

矢量图与位图区别

文章目录 目的区别 目的 了解矢量图与位图区别。 区别 矢量图和位图是两种不同类型的图形图像&#xff0c;它们之间的主要区别在于存储和表示图像的方式&#xff0c;以及在不同应用场景下的优势和劣势。 项目Vector GraphicsBitmap存储方式矢量图使用数学公式和几何图形的描…

linux /proc 文件系统

/proc系统是一个伪文件系统&#xff0c;它只存在内存当中&#xff0c;而不占用外存空间&#xff0c;以文件系统的方式为内核与进程提供通信的接口。 /proc目录下有很多以数字命名的目录&#xff0c;每个数字代表进程号PID它们是进程目录。系统中当前运行的每一个进程在/proc下都…

【C++】异常处理 ② ( 异常捕获类型 | 异常捕获机制 - 严格匹配异常类型 | 未知异常捕获 - 不知道异常类型 )

文章目录 一、异常捕获机制 - 严格匹配异常类型1、异常捕获机制 - 严格匹配异常类型2、代码示例 - 异常捕获严格匹配异常类型 二、异常捕获机制 - 未知异常捕获1、未知异常捕获 - 不知道异常类型2、代码示例 - 未知异常捕获 一、异常捕获机制 - 严格匹配异常类型 1、异常捕获机…

Echarts大屏-数据可视化

使用原生htmljavascript实现大屏展示,较为麻烦的为边框的四个小角使用伪元素生成,其余echarts使用如下快速上手 - Handbook - Apache ECharts 效果如下:

【算法】状压DP-1

状压DP 介绍介绍例子 剖析P4802 [CCO2015] 路短最题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 提示 分析Code 介绍 介绍 状态压缩就是使用某种方法&#xff0c;简明扼要地以最小代价来表示某种状态&#xff0c;通常是用一串01数字&#xff08;二进制数&#xff0…

java论坛数据以及搜索接口实现

一. 内容简介 java论坛数据以及搜索接口实现 二. 软件环境 2.1 java 1.8 2.2 mysql Ver 8.0.13 for Win64 on x86_64 (MySQL Community Server - GPL) 2.3 IDEA ULTIMATE 2019.3 2.4d代码地址 三.主要流程 3.1 创建数据库,创建数据表 3.2 开始编写接口&#xff0c;并测…

几种攻击方式

对抗攻击 Adversarial evasion&#xff08;对抗性逃避&#xff09;是指针对机器学习模型的一种攻击方式&#xff0c;旨在通过对输入数据进行微小但精心设计的修改&#xff0c;使模型产生错误的输出。这种攻击通常是有意识地利用模型的弱点&#xff0c;以便误导模型做出错误的决…