Linux 下 socket 编程介绍及 TCP 客户端与服务端创建示例
目录
- socket 编程接口
- TCP 服务端
- TCP 客户端
- 更多内容
本文介绍了 Linux 下的 socket 编程,及总结了使用 socket 接口实现 TCP 服务端和客户端的示例代码。
socket 编程接口
- socket() 函数:用于创建一个新的 socket 描述符:
int socket(int domain, int type, int protocol);
其中,domain 指定协议族(如 AF_INET 表示 IPv4),type 指定 socket 类型(如 SOCK_STREAM 表示 TCP,SOCK_DGRAM 表示 UDP),protocol 通常设置为 0,表示使用默认协议。
- bind() 函数:将 socket 绑定到一个 IP 地址或端口上:
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
其中,sockfd 是 socket 描述符,addr 是指向 struct sockaddr 的指针,包含了 IP 地址和端口号信息,addrlen 是 struct sockaddr 的大小。
- listen() 函数:用于监听一个 socket 上的连接请求:
int listen(int sockfd, int backlog);
其中,sockfd 是 socket 描述符,backlog 指定了等待连接的最大队列长度。
- accept() 函数:从监听 socket 的等待队列中接受一个连接:
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
该函数返回一个新的 socket 描述符,用于与客户端进行通信,addr 和 addrlen 用于获取客户端的地址信息。
- connect() 函数:用于建立一个到服务器的连接:
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
其中,sockfd 是 socket 描述符,addr 是指向 struct sockaddr 的指针,包含了服务器的 IP 地址和端口号信息。
- send() 和 recv() 函数:用于通过 socket 发送和接收数据:
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 是控制函数行为的标志。
- close() 函数:用于关闭一个 socket:
int close(int sockfd);
其中,sockfd 是 socket 描述符。
- 在 Linux 下进行 socket 编程时,通常还需要处理错误和异常情况,以及进行地址转换(使用 inet_ntop 和 inet_pton 函数)和字节序转换(使用 htons 和 ntohs 函数)等操作。
TCP 服务端
- tcp_server.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <sys/time.h>
#include <errno.h>
#include "tcp_server.h"char buffer[BUFFER_SIZE] = {0};int server_init_socket(void)
{int socket_fd;struct sockaddr_in address;if ((socket_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {perror("socket failed");exit(EXIT_FAILURE);}address.sin_family = AF_INET;address.sin_addr.s_addr = INADDR_ANY;address.sin_port = htons(PORT);if (bind(socket_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {perror("bind failed");exit(EXIT_FAILURE);}if (listen(socket_fd, 3) < 0) {perror("listen");exit(EXIT_FAILURE);}return socket_fd;
}int server_set_socket_timeout(int socket_fd, long milliseconds)
{struct timeval tv;tv.tv_sec = milliseconds / 1000; tv.tv_usec = (milliseconds % 1000) * 1000;if (setsockopt(socket_fd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof(tv)) < 0) {perror("setsockopt SO_RCVTIMEO");exit(EXIT_FAILURE);}return 0;
}int server_accept_client(int socket_fd)
{struct sockaddr_in address;int addrlen = sizeof(address);int temp_fd = accept(socket_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen);if (temp_fd < 0) {perror("accept");exit(EXIT_FAILURE);}printf("Connection established with %s:%d\n", inet_ntoa(address.sin_addr), ntohs(address.sin_port));return temp_fd;
}int server_receive_data(int socket_fd, char *message, ssize_t *size)
{ssize_t bytes_received = recv(socket_fd, message, BUFFER_SIZE, 0);if (bytes_received == -1) {if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ETIMEDOUT){printf("socket recv time out \r\n");return 1;} else {perror("recv");exit(EXIT_FAILURE);}}*size = bytes_received;return 0;
}void server_send_data(int socket_fd, const char *message, ssize_t size)
{if (send(socket_fd, message, size, 0) < 0) {perror("send");exit(EXIT_FAILURE);}
}int server_check_tcp_connection(int socket_fd)
{int error = 0;socklen_t len = sizeof(error);if (getsockopt(socket_fd, SOL_SOCKET, SO_ERROR, &error, &len) == 0) {if (error == 0) {return 1;}}return 0;
}int server_close_socket(int socket_fd)
{close(socket_fd);return 0;
}
- tcp_server.h
#ifndef __TCP_SERVER__
#define __TCP_SERVER__#include <sys/socket.h>#define PORT 8080
#define BUFFER_SIZE 1024extern char buffer[BUFFER_SIZE];int server_init_socket(void);
int server_accept_client(int socket_fd);
int server_set_socket_timeout(int socket_fd, long milliseconds);
int server_receive_data(int socket_fd, char *message, ssize_t *size) ;
void server_send_data(int socket_fd, const char *message, ssize_t size);
int server_check_tcp_connection(int socket_fd);
int server_close_socket(int fd);#endif
- main.c
#include <stdio.h>
#include "tcp_server.h"int main(void)
{int server_fd, client_fd;char recv_buffer[1024];ssize_t size = 0;server_fd = server_init_socket();client_fd = server_accept_client(server_fd);server_send_data(client_fd, "Hello TCP!", 10);server_receive_data(client_fd, recv_buffer, &size);printf("%s", recv_buffer);return 0;
}
TCP 客户端
- tcp_client.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>#include "tcp_client.h"int client_init_socket(void)
{int socket_fd;struct sockaddr_in server_address;if ((socket_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {perror("socket failed");exit(EXIT_FAILURE);}server_address.sin_family = AF_INET;server_address.sin_addr.s_addr = inet_addr(SERVER_IP);server_address.sin_port = htons(SERVER_PORT);if (connect(socket_fd, (struct sockaddr *)&server_address, sizeof(server_address)) < 0) {perror("connect");exit(EXIT_FAILURE);}return socket_fd;
}int client_receive_data(int socket_fd, char *message, ssize_t *size)
{ssize_t bytes_received = recv(socket_fd, message, BUFFER_SIZE, 0);if (bytes_received == -1) {perror("recv");exit(EXIT_FAILURE);}*size = bytes_received;return 0;
}void client_send_data(int socket_fd, const char *message, ssize_t size)
{if (send(socket_fd, message, size, 0) < 0) {perror("send");exit(EXIT_FAILURE);}
}int client_check_tcp_connection(int socket_fd)
{int error = 0;socklen_t len = sizeof(error);if (getsockopt(socket_fd, SOL_SOCKET, SO_ERROR, &error, &len) == 0) {if (error == 0) {return 1;}}return 0;
}int client_close_socket(int socket_fd)
{close(socket_fd);return 0;
}
- tcp_client.h
#ifndef __TCP_CLIENT_H__
#define __TCP_CLIENT_H__#include <sys/socket.h>#define SERVER_IP "192.168.0.123"
#define SERVER_PORT 8080
#define BUFFER_SIZE 1024int client_init_socket(void);
int client_receive_data(int socket_fd, char *message, ssize_t *size);
void client_send_data(int socket_fd, const char *message, ssize_t size);
int client_check_tcp_connection(int socket_fd);
int client_close_socket(int socket_fd);#endif
- main.c
#include <stdio.h>
#include "tcp_client.h"int main(void)
{int client_fd = 0;char buffer[1024];ssize_t size = 0;client_fd = client_init_socket();client_send_data(client_fd, "Hello TCP!", 10);client_receive_data(client_fd, buffer, &size);printf("%s", recv_buffer);return 0;
}
更多内容
- CSDN博客:@Hello阿尔法
- 哔哩哔哩:@Hello阿尔法
- 知乎:@Hello阿尔法
相关文章:
Linux 下 socket 编程介绍及 TCP 客户端与服务端创建示例
目录 socket 编程接口TCP 服务端TCP 客户端更多内容 本文介绍了 Linux 下的 socket 编程,及总结了使用 socket 接口实现 TCP 服务端和客户端的示例代码。 socket 编程接口 socket() 函数:用于创建一个新的 socket 描述符: int socket(int …...
JetBrains Gateway Github Copilot 客户端插件和主机插件
JetBrains Gateway可以通过插件支持Github Copilot(需另行注册)。 需要安装插件 客户端,而非插件 主机,如图所示: 大概是因为代码显示在客户端(运行在本地的IDE)?...
【web APIs】3、(学习笔记)有案例!
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、概念其他事件页面加载事件元素滚动事件页面尺寸事件 元素尺寸与位置 二、案例举例电梯导航 前言 掌握阻止事件冒泡的方法理解事件委托的实现原理 一、概念…...
使用css reset 还是使用Normalize.css
文章目录 使用css reset 还是使用Normalize.cssCSS Reset:Normalize.css:总结Normalize.css 的使用(例如Vue 3.0 和 Vue CLI 4.x 项目)1.安装2.main.js 中导入3.测试引用是否成功。 使用css reset 还是使用Normalize.css 使用 CSS Reset 还是 Normalize…...
英语中的提问方式(问法)(bug提问、bug描述)
文章目录 英语提问方式一、单词、短语、句子的意思1.1 提问单词的意思1.2 提问短语的意思1.3 提问句子的意思 二、在编程中提问2.1 提问bug2.2 请求代码帮助 如何提出反问句1. 构建反问句的基本结构2. 提问反问句的方法3. 理解反问句的意图 在口语中提问:确保清晰度…...
xss.haozi.me靶机练习
目录 第零关: 第一关: 第二关: 第三关: 第四关: 第五关: 第六关: 第七关: 第八关: 第九关: 第十关: 第十一关: 第十二关…...
2.1 mov、add和sub加减指令实操体验
汇编语言 1. mov操作 1.1 mov移动值 mov指令把右边的值移动到左边 mount c d:masm c: debug r ax 0034 r 073f:0100 mov ax,7t1.2 mov移动寄存器的值 把右边寄存器的值赋值给左边的寄存器 a 073f:0105 mov bx,axt1.3 mov高八位(high)和低八位&am…...
计算机设计大赛 深度学习机器视觉车道线识别与检测 -自动驾驶
文章目录 1 前言2 先上成果3 车道线4 问题抽象(建立模型)5 帧掩码(Frame Mask)6 车道检测的图像预处理7 图像阈值化8 霍夫线变换9 实现车道检测9.1 帧掩码创建9.2 图像预处理9.2.1 图像阈值化9.2.2 霍夫线变换 最后 1 前言 🔥 优质竞赛项目系列,今天要分…...
中间件安全(概述)有中间件的各类链接和官网信息和漏洞库以及配置问题和开源工具
分类主要包括Apache、IIS、Tomcat、weblogic、websphere、Jboss等相关的技术知识和实践。 以Apache为例讲一讲如何保证中间件安全 中间件安全是指保护中间件软件和服务的安全性,防止被恶意攻击或者滥用。中间件软件是指在操作系统和应用程序之间提供通信和集成功能…...
Unity铰链四杆机构设计和运动仿真
一、效果图 设定好各边长度和转速后,点击【设置并启动】,自动生成一个机构模型,并按照原理进行运转 二、铰链四杆机构介绍 机架:A和D是固定位置,叫做机架。 曲柄:B点绕A点旋转,构成曲柄。 连…...
Python爬虫——解析常用三大方式之Xpath
目录 Xpath 安装xpath 安装lxml库 导入lxml库 解析本地文件 etree.parse() 解析服务器响应文件 etree.HTML() xpath基本语法 小案例:获取百度首页的百度一下 大案例:爬取站长素材图片 总结 Xpath 安装xpath 首先要学会安…...
C#判断DataTable1 A列的集合是否为DataTable2 B列的集合的子集
DataSet ds2 (DataSet)res2.Anything; // 检查 集合B是否为集合A的子集 var table1MaterialCodes ds.Tables[2].AsEnumerable().Select(row > row["Code"]).ToList(); //DataSet1 表Code列集合A var table2MaterialCodes ds2.Tables[0].AsEnumerable().Selec…...
VirtualBox 桥接网卡 未指定 “未能启动虚拟电脑Ubuntu,由于下述物理网卡未找到:”
解决办法,安装虚拟网卡,win11查找方式:控制面板→网络和共享中心→更改适配器设置 此时出现下面情况就算安装成功 但是如果报错:找不到指定的模块 则按下面步骤删除干净垃圾重新上面操作 先安装CCleaner, 链接:CCleaner Makes Y…...
基于yolov5的电瓶车和自行车检测系统,可进行图像目标检测,也可进行视屏和摄像检测(pytorch框架)【python源码+UI界面+功能源码详解】
功能演示: 基于yolov5的电瓶车和自行车检测系统_哔哩哔哩_bilibili (一)简介 基于yolov5的电瓶车和自行车检测系统是在pytorch框架下实现的,这是一个完整的项目,包括代码,数据集,训练好的模型…...
vscode如何远程到linux python venv虚拟环境开发?(python虚拟环境、vscode远程开发、vscode远程连接)
文章目录 1. 安装VSCode2. 安装扩展插件3. 配置SSH连接4. 输入用户名和密码5. 打开远程文件夹6. 创建/选择Python虚拟环境7. 安装Python插件 Visual Studio Code (VSCode) 提供了一种称为 Remote Development 的功能,允许用户在远程系统、容器或甚至 Windows 子系统…...
蓝桥杯第十二届电子类单片机组程序设计
目录 前言 蓝桥杯大赛历届真题_蓝桥杯 - 蓝桥云课(点击查看) 单片机资源数据包_2023(点击下载) 一、第十二届比赛原题 1.比赛题目 2.题目解读 蓝桥杯第十四届电子类单片机组程序设计_蓝桥杯单片机哪一届最难-CSDN博客 二、…...
基于springboot+vue的工作流程管理系统
博主主页:猫头鹰源码 博主简介:Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战,欢迎高校老师\讲师\同行交流合作 主要内容:毕业设计(Javaweb项目|小程序|Pyt…...
【LeetCode刷题】146. LRU 缓存
请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。 实现 LRUCache 类: LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -…...
奇酷网络用AI思维办公:不允许做PPT,只能用Word,只能一页纸
在AI时代,视频制作领域正经历着一场革命。Sora 作为首个文生视频大模型,可能攻克了自然语言处理、计算机视觉和深度学习等难点,使视频生成更真实、自然。奇酷网络是一家很另类、很奇怪的“AI游戏”创业公司,奇酷网络董事长吴渔夫(…...
【笔记】-编程语言以及应用领域
C/C 永远不会衰败的语言,适合偏底层,例如:Windows操作系统80%以上都是由C/C完成的,C/C也集成用于写应用层C/S架构的软件 JAVA 是真正的跨平台的语言 “一次编程,到处使用”Java适合应用层的开发,无论是…...
使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造,完美适配AGV和无人叉车。同时,集成以太网与语音合成技术,为各类高级系统(如MES、调度系统、库位管理、立库等)提供高效便捷的语音交互体验。 L…...
网络六边形受到攻击
大家读完觉得有帮助记得关注和点赞!!! 抽象 现代智能交通系统 (ITS) 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 (…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...
ardupilot 开发环境eclipse 中import 缺少C++
目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...
智能仓储的未来:自动化、AI与数据分析如何重塑物流中心
当仓库学会“思考”,物流的终极形态正在诞生 想象这样的场景: 凌晨3点,某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径;AI视觉系统在0.1秒内扫描包裹信息;数字孪生平台正模拟次日峰值流量压力…...
Java线上CPU飙高问题排查全指南
一、引言 在Java应用的线上运行环境中,CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时,通常会导致应用响应缓慢,甚至服务不可用,严重影响用户体验和业务运行。因此,掌握一套科学有效的CPU飙高问题排查方法&…...
浪潮交换机配置track检测实现高速公路收费网络主备切换NQA
浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求,本次涉及的主要是收费汇聚交换机的配置,浪潮网络设备在高速项目很少,通…...
GruntJS-前端自动化任务运行器从入门到实战
Grunt 完全指南:从入门到实战 一、Grunt 是什么? Grunt是一个基于 Node.js 的前端自动化任务运行器,主要用于自动化执行项目开发中重复性高的任务,例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...
JavaScript基础-API 和 Web API
在学习JavaScript的过程中,理解API(应用程序接口)和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能,使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...
