Linux网络编程-极简HTTPUDP服务器
HTTP服务器
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>#define PORT 8080
#define BUFFER_SIZE 2048void handle_client(int client_socket) {char buffer[BUFFER_SIZE];recv(client_socket, buffer, sizeof(buffer) - 1, 0); printf("Received request:\n%s\n", buffer);char response[] = "HTTP/1.1 200 OK\r\n""Content-Type: text/plain\r\n""Content-Length: 15\r\n""Connection: close\r\n\r\n""Hello, World!\r\n";send(client_socket, response, sizeof(response) - 1, 0); close(client_socket);
}int main() {int server_socket, client_socket;struct sockaddr_in server_address, client_address;socklen_t client_len;server_socket = socket(AF_INET, SOCK_STREAM, 0);if (server_socket == -1) {perror("Could not create socket");exit(1);}server_address.sin_family = AF_INET;server_address.sin_addr.s_addr = INADDR_ANY;server_address.sin_port = htons(PORT);if (bind(server_socket, (struct sockaddr *)&server_address, sizeof(server_address)) == -1) {perror("Bind failed");exit(1);}if (listen(server_socket, 10) == -1) {perror("Listen failed");exit(1);}printf("HTTP server is running on port %d ...\n", PORT);while (1) {client_len = sizeof(client_address);client_socket = accept(server_socket, (struct sockaddr *)&client_address, &client_len);if (client_socket == -1) {perror("Accept failed");continue;}handle_client(client_socket);}close(server_socket);return 0;
}
HTTP客户端
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>#define SERVER_PORT 8080
#define BUFFER_SIZE 2048int main(int argc, char *argv[]) {int client_socket;struct sockaddr_in server_address;char buffer[BUFFER_SIZE];// 检查命令行参数if (argc != 2) {printf("Usage: %s <Server IP>\n", argv[0]);exit(1);}client_socket = socket(AF_INET, SOCK_STREAM, 0);if (client_socket == -1) {perror("Could not create socket");exit(1);}server_address.sin_family = AF_INET;server_address.sin_port = htons(SERVER_PORT);if (inet_pton(AF_INET, argv[1], &server_address.sin_addr) <= 0) {perror("inet_pton() failed");exit(1);}// 连接到服务器if (connect(client_socket, (struct sockaddr *)&server_address, sizeof(server_address)) == -1) {perror("Connect failed");close(client_socket);exit(1);}// 向服务器发送HTTP请求char request[] = "GET / HTTP/1.1\r\nHost: localhost\r\n\r\n";send(client_socket, request, strlen(request), 0);// 接收服务器响应int bytes_received = recv(client_socket, buffer, BUFFER_SIZE - 1, 0);if (bytes_received == -1) {perror("Error receiving data");close(client_socket);exit(1);}buffer[bytes_received] = '\0';printf("Received from server:\n%s\n", buffer);close(client_socket);return 0;
}
或者在浏览器或者使用curl工具访问http://localhost:8080,也能够看到来自服务器的“Hello, World!”响应。
curl http://localhost:8080
curl -X POST -d "param1=value1¶m2=value2" http://localhost:8080
UDP服务器
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>#define PORT 8080
#define BUFFER_SIZE 2048void handle_client(int server_socket, struct sockaddr_in *client_address, socklen_t client_len) {char buffer[BUFFER_SIZE];int bytes_received = recvfrom(server_socket, buffer, sizeof(buffer) - 1, 0, (struct sockaddr *)client_address, &client_len);if (bytes_received == -1) {perror("Error receiving data");return;}buffer[bytes_received] = '\0';printf("Received request from %s:%d\n%s\n", inet_ntoa(client_address->sin_addr), ntohs(client_address->sin_port), buffer);char response[] = "Hello, World from UDP!";sendto(server_socket, response, sizeof(response) - 1, 0, (struct sockaddr *)client_address, client_len);
}int main() {int server_socket;struct sockaddr_in server_address, client_address;socklen_t client_len;server_socket = socket(AF_INET, SOCK_DGRAM, 0);if (server_socket == -1) {perror("Could not create socket");exit(1);}server_address.sin_family = AF_INET;server_address.sin_addr.s_addr = INADDR_ANY;server_address.sin_port = htons(PORT);if (bind(server_socket, (struct sockaddr *)&server_address, sizeof(server_address)) == -1) {perror("Bind failed");exit(1);}printf("UDP server is running on port %d...\n", PORT);while (1) {client_len = sizeof(client_address);handle_client(server_socket, &client_address, client_len);}close(server_socket);return 0;
}
UDP客户端
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>#define SERVER_PORT 8080
#define BUFFER_SIZE 2048int main(int argc, char *argv[]) {int client_socket;struct sockaddr_in server_address;char buffer[BUFFER_SIZE];// 检查命令行参数if (argc != 2) {printf("Usage: %s <Server IP>\n", argv[0]);exit(1);}client_socket = socket(AF_INET, SOCK_DGRAM, 0);if (client_socket == -1) {perror("Could not create socket");exit(1);}memset(&server_address, 0, sizeof(server_address));server_address.sin_family = AF_INET;server_address.sin_port = htons(SERVER_PORT);if (inet_pton(AF_INET, argv[1], &server_address.sin_addr) <= 0) {perror("inet_pton() failed");exit(1);}// 向服务器发送消息char message[] = "Hello, UDP Server!";sendto(client_socket, message, strlen(message), 0, (struct sockaddr *)&server_address, sizeof(server_address));// 接收来自服务器的响应int bytes_received = recvfrom(client_socket, buffer, BUFFER_SIZE - 1, 0, NULL, NULL);if (bytes_received == -1) {perror("Error receiving data");exit(1);}buffer[bytes_received] = '\0';printf("Received from server: %s\n", buffer);close(client_socket);return 0;
}
或者使用以下命令向UDP服务器发送数据:
echo "Your message here" | nc -u -w1 localhost 8080
为什么 send() 和 recv() 适用于TCP而不是UDP
TCP (Transmission Control Protocol) 是一个面向连接的协议。当我们谈论TCP连接时,我们指的是一个由客户端套接字和服务器套接字组成的持久的网络连接。这意味着,一旦建立了TCP连接,双方都知道对方的IP地址和端口号,因此不需要在每次数据交换时重新指定。
由于这种固定的连接特性,当我们想要通过已经建立的TCP连接发送或接收数据时,不需要再次指定远程的地址和端口。这就是为什么 send() 和 recv() 适用于TCP:它们只发送和接收数据,不涉及地址信息。
另一方面,UDP (User Datagram Protocol) 是一个无连接的协议。这意味着每次数据包的发送都是独立的,没有固定的连接或对端信息与其相关联。因此,当我们使用UDP发送数据时,需要指定要将数据发送到的地址和端口。这就是 sendto() 和 recvfrom() 的用途。
总结:
- TCP是面向连接的,一旦连接建立,系统就知道数据将被发送到哪里,因此只需要
send()和recv()。 - UDP是无连接的,所以每次发送数据都需要指定目的地,这就是为什么需要
sendto()和recvfrom()。
当然,技术上可以为UDP使用 connect() 来设置默认的远程地址和端口,然后使用 send() 和 recv(),但这样做是非典型的,并可能导致与UDP的无连接特性不一致的行为。
当我们说SOCK_STREAM(如TCP)为我们提供了一个连续的字节流,并且没有内在的消息边界,这是什么意思呢?
-
连续的字节流:
- 当我们使用TCP发送数据,是在向一个开放的连接发送一个连续的字节流。例如,如果连续调用三次
send()函数,发送三个字符串,它们可能会被接收端作为一个连续的字节流接收。 - 不存在固定的消息大小或结构,我们可以任意发送任何大小的数据。
- 当我们使用TCP发送数据,是在向一个开放的连接发送一个连续的字节流。例如,如果连续调用三次
-
没有内在的消息边界:
- 在TCP中,数据的发送和接收是流式的,没有固定的消息边界。这意味着,如果发送方连续发送了两个数据块,接收方没有办法仅通过TCP来知道这两个数据块是如何分隔的。接收方可能在一个
recv()调用中接收到两个数据块的部分或全部。 - 例如,如果发送方连续执行两次
send(),分别发送字符串"HELLO"和"WORLD",接收方可能需要多次recv()调用来接收这些数据,或者可能在一个recv()调用中接收到字符串"HELLOWORLD"。
- 在TCP中,数据的发送和接收是流式的,没有固定的消息边界。这意味着,如果发送方连续发送了两个数据块,接收方没有办法仅通过TCP来知道这两个数据块是如何分隔的。接收方可能在一个
这种没有消息边界的特性与SOCK_DGRAM(如UDP)形成了对比,在UDP中,每个sendto()调用发送的数据都被视为一个独立的消息,且在接收端通过一个recvfrom()调用完整地接收。
这就是为什么在使用TCP时,应用程序往往需要自己实现某种消息边界的机制,例如通过使用特定的分隔符、固定长度的头部或其他协议来定义消息的开始和结束。
SOCK_DGRAM 提供了一个有边界的服务。这意味着,当我们使用 SOCK_DGRAM(如UDP)发送一个数据报,接收端会将这个数据报作为一个整体进行处理,不会将它与其他数据报合并或分割。每个 sendto() 调用对应一个完整且单独的消息,该消息在接收端使用一个 recvfrom() 调用完整接收。
换句话说,数据报协议保留了消息边界。例如,如果发送方调用了两次 sendto(),接收方也必须调用两次 recvfrom() 来接收这两条消息。这与 SOCK_STREAM(如TCP)不同,在流式协议中,数据是一个连续的字节流,没有内在的消息边界。
关于curl命令和nc命令的详细介绍以及网络编程中常用的函数说明,读者可移步至以下博客:
Linux- curl命令
Linux中的nc命令
Linux网络编程- recvfrom() & sendto()
Linux- 网络编程初探
相关文章:
Linux网络编程-极简HTTPUDP服务器
HTTP服务器 #include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <arpa/inet.h>#define PORT 8080 #define BUFFER_SIZE 2048void handle_client(int client_socket) {char buffer[BUFFER_SIZE];recv(cl…...
虚拟化、容器与Docker基本介绍以及安装部署(Docker 基本管理)
目录 1 Docker 概述 1.1 Docker与虚拟机的区别 1.2 容器在内核中支持2种重要技术 1.3 Docker核心概念 2 安装 Docker 2 Docker 镜像操作 2.1 搜索镜像 2.2 获取镜像 2.3 镜像加速下载 2.4 查看镜像信息 2.4.1 查看下载的镜像文件信息 2.4.2 查看下载到本地的所有镜像…...
Spring Boot中捕获异常错误信息并将其保存到数据库中
Spring Boot中捕获异常错误信息并将其保存到数据库中: 1.创建数据库表: 首先,您需要创建一个用于存储异常信息的数据库表。可以使用SQL脚本或者使用Hibernate实体类来创建表。以下是一个用于存储异常信息的表的示例SQL: CREATE TABLE erro…...
CNN记录】pytorch中flatten函数
pytorch原型 torch.flatten(input, start_dim0, end_dim- 1) 作用:将连续的维度范围展平维张量,一般写再某个nn后用于对输出处理, 参数: start_dim:开始的维度 end_dim:终止的维度,-1为最后…...
科普长文--网络安全拟态防御技术概念及应用
网络安全拟态防御技术概念 什么是网络安全拟态防御? 网络安全拟态防御技术是一种基于生物拟态原理,利用动态异构冗余构造、拟态伪装机制、测不准效应等手段,实现网络空间的主动防御和内生安全的技术。它是由中国工程院院士邬江兴首创的,旨在应对网络空间中的各种未知威胁…...
框架篇
一、Spring中的单例Bean是线程安全的吗 二、AOP相关面试题 三、Spring中的事务 四、Spring中事务失效的场景有 五、Spring bean的生命周期 六、Spring的循环依赖 七、SpringMVC的执行流程 八、自动配置原理 九、Spring框架常见的注解 十、Mybatis的执行流程 十一、MyBatis延迟加…...
Spring MVC(中)
1、Spring MVC视图: SpringMVC中的视图是View接口,视图的作用渲染数据,将模型Model中的数据展示给用户 SpringMVC视图的种类很多,默认有转发视图和重定向视图 当工程引入jstl的依赖,转发视图会自动转换为JstlView …...
10月19日,每日信息差
今天是2023年10月19日,以下是为您准备的17条信息差 第一、中国海洋石油遭南向资金净卖出2.38亿港元 第二、阅文集团侯晓楠:网文已经成为中国文化的一张全球名片。据了解,2022年以来,阅文已经在海外上线了自制的300多部动漫影视作…...
【VSCode】解决Open in browser无效
问题描述: 在VSCode中无论是点击右键,选择在默认浏览器中打开,还是按快捷键alt b都没有反应。 解决办法: 右击文件 --> 在文件资源管理器中显示 右击文件,选择属性 点击更改 选择用默认浏览器打开 最后 此时…...
测试饱和了? 大数据测试就业薪资和前景究竟怎么样?
随着不断有转行人员及毕业的大学生进入IT行业,在很多外界人眼里,这个行业的“缺口”已满,人员趋于饱和,但事实真的这样吗?还真没有。只是最基础的岗位需求在慢慢变少了,但行业中比较深的细分岗位࿰…...
DDR3笔记 频率配置
可参考 基于FPGA的DDR3设计(2)DDR3各时钟频率及带宽分析 - 知乎 (zhihu.com) DDR3的时钟频率配置要看两个手册: 1.DDR3器件的手册。 2.开发板芯片的手册 器件 器件名称:MT41J128M16JT-125:K tCK 1.25ns,就可以算出…...
数据结构与算法-(10)---列表(List)
🌈write in front🌈 🧸大家好,我是Aileen🧸.希望你看完之后,能对你有所帮助,不足请指正!共同学习交流. 🆔本文由Aileen_0v0🧸 原创 CSDN首发🐒 如…...
Node-Web模块的用法
题记 node.js中web模块的用法,以下是具体操作过程和代码。 Web服务器一般指网站服务器,是指驻留于因特网上某种类型计算机的程序,Web服务器的基本功能就是提供Web信息浏览服务。它只需支持HTTP协议、HTML文档格式及URL,与客户端的…...
基于TCP的RPC服务
TCP服务器上的RPC,通过创建一个服务器进程监听传入的tcp连接,并允许用户 通过此TCP流执行RPC命令 -module(tr_server). -author("chen"). -behaviour(gen_server).%% API -export([start_link/1,start_link/0,get_count/0,stop/0 ]).-export(…...
docker报错问题解决:Error Invalid or corrupt jarfile app.jar
文章目录 1.问题描述2.问题分析3.问题解决 1.问题描述 此时处在 /home/ubuntu/app 目录下,并且在该目录下有一个 jenkins-0.0.1-SNAPSHOT.jar。 我在 /home/ubuntu/app 目录下执行了 docker 容器运行命令: # 映射 8859 端口 # 容器名为 jenkins-demo #…...
Day 09 python学习笔记
函数 装饰器 回顾内容: 函数可以作为参数进行传递函数可以作为返回值函数名称可以像变量一样进行赋值操作 装饰器:要求记住结论 引入: def play_dnf():print("你好啊,我是赛利亚,今天又是美好的一天")def p…...
力扣labuladong——一刷day02
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、力扣876. 链表的中间结点二、力扣142. 环形链表 II三、力扣160. 相交链表四、力扣141. 环形链表 前言 一、力扣876. 链表的中间结点 /*** Definition for …...
【小白专用23.10.22 已验证】windows 11 安装PHP8.2 +Apache2.4
环境说明 windows:windows 11 x64apache: Apache/2.4.43php :php-8.2.11 一.php 1、PHP下载 PHP For Windows: Binaries and sources Releases 注意: 1.要下载Thread Safe,否则没有php8apache2_4.dll这个文件;如果使用Apache作为服务器…...
Nmap端口服务 之 CentOS7 关于启动Apache(httpd)服务、telnet服务、smtp服务、ftp服务、sftp服务
Nmap端口服务 之 CentOS7 关于启动Apache(httpd)服务、telnet服务、smtp服务、ftp服务、sftp服务 一. CentOS7 安装配置SFTP服务器详解一、SFTP简介二、关闭防火墙三、安装SSH服务在CentOS7中,sftp只是ssh的一部分,所以采用yum来安装ssh服务即可1. 查看是否已经安装了ssh2.…...
为什么 glBegin 未被定义 未定义的标识符,使用新的 API(LearnOpenGL P2)
文章目录 弃用的 glBegin & glEnd使用新 API 的示例 弃用的 glBegin & glEnd 环境:glfw 3.3.8 glad core OpenGL 初学者在尝试使用 glBegin 和 glEnd 函数来绘制三角形时,有可能找到使用这些函数的文章、代码文献 但许多这些函数已经在OpenG…...
SpringBoot-17-MyBatis动态SQL标签之常用标签
文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...
UDP(Echoserver)
网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法:netstat [选项] 功能:查看网络状态 常用选项: n 拒绝显示别名&#…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...
C#中的CLR属性、依赖属性与附加属性
CLR属性的主要特征 封装性: 隐藏字段的实现细节 提供对字段的受控访问 访问控制: 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性: 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑: 可以…...
车载诊断架构 --- ZEVonUDS(J1979-3)简介第一篇
我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 做到欲望极简,了解自己的真实欲望,不受外在潮流的影响,不盲从,不跟风。把自己的精力全部用在自己。一是去掉多余,凡事找规律,基础是诚信;二是…...
简单介绍C++中 string与wstring
在C中,string和wstring是两种用于处理不同字符编码的字符串类型,分别基于char和wchar_t字符类型。以下是它们的详细说明和对比: 1. 基础定义 string 类型:std::string 字符类型:char(通常为8位)…...
无需布线的革命:电力载波技术赋能楼宇自控系统-亚川科技
无需布线的革命:电力载波技术赋能楼宇自控系统 在楼宇自动化领域,传统控制系统依赖复杂的专用通信线路,不仅施工成本高昂,后期维护和扩展也极为不便。电力载波技术(PLC)的突破性应用,彻底改变了…...
【Qt】控件 QWidget
控件 QWidget 一. 控件概述二. QWidget 的核心属性可用状态:enabled几何:geometrywindows frame 窗口框架的影响 窗口标题:windowTitle窗口图标:windowIconqrc 机制 窗口不透明度:windowOpacity光标:cursor…...
关于 ffmpeg设置摄像头报错“Could not set video options” 的解决方法
若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/148515355 长沙红胖子Qt(长沙创微智科)博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV…...
XXE漏洞知识
目录 1.XXE简介与危害 XML概念 XML与HTML的区别 1.pom.xml 主要作用 2.web.xml 3.mybatis 2.XXE概念与危害 案例:文件读取(需要Apache >5.4版本) 案例:内网探测(鸡肋) 案例:执行命…...
