Linux网络编程——Socket编程步骤及常用API
Sockt服务器和客户端的开发步骤
TCP

connect()最好建立在listen()后,一旦监听到就建立连接。

UDP


常用API
包含头文件
#include<sys/types.h>
#include<sys/socket.h>
创建套接字(连接协议)
作用
用于根据指定的地址族、数据类型和协议来分配一个套接口的描述字及其所用的资源的函数。
函数原型
int socket(int domain,int type, int protocol);
参数解读
domain:指明所使用的协议族/域。
常用的domain类型有:
- AF_INET IPv4——因特网域
- AF_INET6 IPv6——因特网域
- AF UNIX Unix——域
- AF ROUTE——路由套接字
- AFKEYE——钥套接字
- AF UNSPEC——未拖定
type:指定socket类型。
常用的socket类型有:
SOCK_STREAM
TCP:流式套接字提供可靠的、面向连接的通信流:它使用TCP协议,从而保证了数据传输的正确性和顺序性。
SOCK_DGRAM
UDP:数据报套接字定义了一种无连按的服,数据通过相互独立的报文进行传输, 是无序的,并且不保证是可靠,无差错的。它使用数据报协议UDP。
SOCK_RAW
允许程序使用低层协议,原始科接字允许对底层协议如IP或ICMP进行直接访问,功能强大但使用较为不便,主要用于一些协议的开发。
protocol:通常赋值 00表示选择type类型对应得默认协议。
IPPROTO_TCP——TCP传输协议IPPTOTO_UDP——UDP传输协议IPPROTO_SCTP——STCP传输协议IPPROTO_TIPC——TIPC传输协议
返回值
成功时返回新的套接字描述符,失败返回 -1。
地址准备(为套接字添加端口号和IP地址)
作用
套接字绑定到一个地址,并制定一个端口号。 将套接字绑定一个IP地址和端口号,因为这两个元素可以在网络环境中唯一地址表示一个进程。
函数原型
int bind(int sockfd, const struct sockaddr *addr,int addrlen);
参数解读
| sockfd | 是一个socket描述符。 |
| *addr | 是一个指向包含有本机IP地址及端口号等信息的sockaddr类型的指针,指向要绑定给sockfd的协议地址结构这个地址结构根据地址创建,socket时的地址协议族的不同而不同。 |
| addrlen | 第二个参数中结构体的长度。 |
ipv4对应的结构体:
第一种:
struct sockaddr{unisgned short as family; //协议族 选择TCP/UDPchar sa data[14]; //IP+端口 以字符串形式传递
};
第二种(常用):
比较常用,但调用时需要转换成第一种结构体名字,转换格式如(struct sockaddr *)
struct sockaddr_in{sa_family_t sin_family; //协议族 一般是IPV4的网络协议in_port t sin_port; //端口号struct in_addr sin_addr;//IP地址结构体unsigned char sin_zero[8];//填充 没有实际意义,只是为跟sockaddh结构在内存中对齐这样两者才能相互转换
};
监听网络连接
作用
listen函数使用主动连接套接字变为被连接套接口,使得一个进程可以接受其它进程的请求,从而成为一个服务器进程。在TCP服务器编程中listen函数把进程变为一个服务器,并指定相应的套接字变为被动连接。
listen函数一般在调用bind之后-调用accept之前调用。
设置处理的最大连接数,listen()并未开始接受连线,只是设置 sockect 的 listen 模式,listen 函数只用于服务器端,服务器进程不知道要与谁连接,因此,它不会主动此要求与某个进程连接,只是一直监听是否有其他客户进程与之连接,然后响应该连接清求,并对它做出处理,一个服务进程可以同时处理多个客户进程的连接。主要就两个功能:将一个未连接的套接字转换为一个被动套接字(监听),规定内核为相应套接字排队的最大连接数。
内核为任何一个给定监听套接字维护两个队列:
(1) 未完成连接队列,每个这样的 SYN 报文段对应其中一项:已由某个客户端发出并到达服务器,而服务正在等待完成相应的 TCP 三次握手过程。这些套接字处于SYN_REVD状态。
(2) 已完成连接队列,每个已完成 TCP 三次握手过程的客户端对应其中一项。这些套接字处于 ESTABLISHED 状态。
函数原型
int listen(SOCKET sockfd, int backlog);
参数解读
| sockfd | socket系统调用返回的服务器端socket描述符 |
| backlog | 指定在请求队列中允许的最大请求数 |
网络连接
作用
accept函数由TCP服务器调用,用于从已完成连接队列队头返回下一个已完成连接。如果已完成连接队列为空,那么进程被投入睡眠。
函数原型
int accept (int sockfd, struct sockaddr *addr, socklen_t *addrlen);
参数解读
| sockfd | socket系统调用返回的服务器端socket描述符 |
| * addr | 指向客户端数据结构sockaddr的指针,其中包括目的端口和IP地址 |
| *addrlen | 参数二sockaddr的长度的地址,可以通过sizeof(struct sockaddr)获得 |
返回值
该函数的返回值是一个新的套接字描述符,返回值是表示已连接的套接字描述符,而第一个参数是服务器监听套接字描述符。一个服务器通常仅仅创建一个监听套接字,它在该服务器的生命周期内一直存在。内核为每个由服务器进程接受的客户连接创建一个已连接套接字(表示 TCP 三次握手已完成),当服务器完成对某个给定客户的服务时,相应的已连接套接字就会被关闭。
客户端连接
作用
该函数用于绑定之后的client 端(客户端),与服务器建立连接。(客户机连接主机)
函数原型
int connect (int sockfd, struct sockaddr *addr, socklen_t addrlen);
参数解读
| sockfd | socket系统调用返回的服务器端socket描述符 |
| * addr | 指向客户端数据结构sockaddr的指针,其中包括目的端口和IP地址 |
| addrlen | 参数二sockaddr的长度,可以通过sizeof(struct sockaddr)获得 |
返回值
成功返回0,遇到错误时返回-1,并且errno 中包含相应的错误码。
TCP数据收发(第一套)
(1)发送
函数原型
ssize_ t send(int s, const void *msg,size_t len,int flags);
参数解读
| s | s为已建立好连接的套接字描述符 |
| * msg | msg指向存放待发送数据的缓冲区 |
| len | len为待发送数据的长度 |
| flags | flags为控制选项,一般设置为0 |
(2)接收
函数原型
ssize t recv(int s, void *buf,size_t len, int flags);
参数解读
| s | s为已建立好连接的套接字描述符 |
| * msg | msg指向存放待发送数据的缓冲区 |
| len | len为待发送数据的长度 |
| flags | flags为控制选项,一般设置为0 |
返回值
函数返回读或写的字节个数,出错则返回-1。
TCP数据收发(第二套)
(1)发送
将buf中的nbytes个字节写入到文件描述符fd中,成功时返回写的字节数。
函数原型
ssize_t write(int fd, const void *buf,size_t nbytes);
参数解读
| fd | fd为已建立好连接的文件描述符 |
| * buf | buf指向存放待发送数据的缓冲区 |
| size_t nbytes | size_t nbytes为待发送数据的长度 |
(2)接收
从fd中读取nbyte个字节到buf中,返回实际所读的的字节数。
函数原型
ssize_t read(int fd,void *buf,size_t nbyte);
参数解读
| fd | fd为已建立好连接的文件描述符 |
| * buf | buf指向存放待发送数据的缓冲区 |
| size_t nbytes | size_t nbytes为待发送数据的长度 |
UDP数据收发(待完善)
UDP数据收发与TCP类似,常用的API是recvmsg()/sendmsg(),revfrom()/sendto0。
地址转换API
字符串转网络
int inet_aton(const char* straddr,struct in_addr *addrp);
作用:把字符串形式的”192.168.1.123"转为网络能识别的格式
网络转字符串
char* inet ntoa(struct in_ addr inaddr);
作用:把网络格式的ip地址转为字符串形式
代码示例
1、服务端与网络实现连接
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdlib.h>int mian()
{int s_fd;//定义一个套接字描述符s_fd = socket(AF_INET,SOCK_STREAM,0);if(s_fd == -1)//返回-1时表示创建失败{perror("socket");exit(-1);}struct sockaddr_in s_addr;//定义一个sockaddr_in类型的结构体(后面需要转为sockaddr类型)s_addr.sin_family = AF_INET;//IPV4的英特网域s_addr.sin_port = htons(8888);//端口号 x86主机是小端 网络是大段 需进行转换 inet_aton("127.0.0.1",&s_addr.sin_addr);//把字符串形式的”127.0.0.1”转为网络能识别的格式//127.0.0.1表示本机地址 ifconfig查询电脑地址bind(s_fd,(struct sockaddr *)&s_addr,sizeof(struct sockaddr_in));//需要注意第二个参数需将原来的sockaddr_in结构体类型转换成sockaddr结构体类型listen(s_fd,10);int c_fd = accept(s_fd,NULL,NULL);//需定义一个fd来接受其返回值 后续对连接的操作是基于fd 若没有接收到数据 则会一直阻塞printf("connect\n");while(1);return 0;
}
编译结果:编译运行后,程序会一直阻塞,打开另一执行程序页面,输入 telnet+电脑地址后 程序接收成功,则会输出connect。
2、服务端连接实现信息交流
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>int main()
{int s_fd;int n_read;//用于判断char readBuf[128]; char *msg = "I get your connect";struct sockaddr_in s_addr;struct sockaddr_in c_addr;memset(&s_addr,0,sizeof(struct sockaddr_in));//对数据进行清空再定义memset(&c_addr,0,sizeof(struct sockaddr_in));s_fd = socket(AF_INET,SOCK_STREAM,0);if(s_fd == -1){perror("socket");exit(-1);}s_addr.sin_family = AF_INET;s_addr.sin_port = htons(8888);inet_aton("127.0.0.1",&s_addr.sin_addr);bind(s_fd,(struct sockaddr *)&s_addr,sizeof(struct sockaddr_in));listen(s_fd,10);int clen = sizeof(struct sockaddr_in);//计算结构体c_addr的大小int c_fd = accept(s_fd,(struct sockaddr *)&c_addr,&clen);if(c_fd == -1){perror("accept");exit(-1);}printf("get connect :%s\n",inet_ntoa(c_addr.sin_addr));//将网络ip地址转为字符串形式 连接成功先输出此行n_read = read(c_fd,readBuf,128);//从c_fd读取128个字节到readBuf中if(n_read == -1)//调用失败返回-1{perror("read");}else{printf("get message:%d,%s\n",n_read,readBuf);}write(c_fd,msg,strlen(msg));return 0;
}

编译运行后,打开另一程序运行界面,输入telnet+电脑地址后 程序接收成功,则会输出connect并将IP地址以字符串形式打印出来,同时输入相应数据另一端会接收成功,实现客户端与客户端信息交流。
相关文章:
Linux网络编程——Socket编程步骤及常用API
Sockt服务器和客户端的开发步骤 TCP connect()最好建立在listen()后,一旦监听到就建立连接。 UDP 常用API 包含头文件 #include<sys/types.h> #include<sys/socket.h>创建套接字(连接协议) 作用 用于根据指定的地址族、数据…...
数据挖掘 K-Means聚类
未格式化之前的代码: import pandas as pd#数据处理 from matplotlib import pyplot as plt#绘图 from sklearn.preprocessing import MinMaxScaler#归一化 from sklearn.cluster import KMeans#聚类 import os#处理文件os.environ["OMP_NUM_THREADS"] …...
医疗卫生行业网络安全需求发展
文章目录 一、行业安全建设需求分析1、等级保护2.0合规建设云计算技术大数据技术物联网技术移动互联网技术2、加强医疗数据安全保护加密存储与传输数据加强数据备份与恢复注重数据脱敏与分级保护3、强化网络安全制度管理完善应急预案与响应机制加强网络安全人员管理二、行业新技…...
【Unity热更新】学会AssetsBundle打包、加载、卸载
本教程详细讲解什么是AssetBundle压缩包机制!然后构建 AssetBundle、加载 AssetBundle 以及卸载 AssetBundle 的简要教程。这一个流程就是热更新! AssetBundles 简介 1.什么是AssetBundles? AssetBundles是Unity中一种用于打包和存储资源(如模型、纹理、声音等)的文件格…...
智能优化算法应用:基于指数分布算法3D无线传感器网络(WSN)覆盖优化 - 附代码
智能优化算法应用:基于指数分布算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用:基于指数分布算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.指数分布算法4.实验参数设定5.算法结果6.…...
vue 监听浏览器关闭或刷新事件
vue 监听浏览器关闭或刷新事件 需求 web项目中使用socket时,涉及到关闭刷新浏览器多次连接问题,其中一个解决方法是在关闭或刷新浏览器时,将连接断开。 代码 <script> export default {// 可以在created、beforeMount或mounted生命…...
VuePress-theme-hope 搭建个人博客 2【快速上手】 —— 安装、部署 防止踩坑篇
续👆VuePress、VuePress-theme-hope 搭建个人博客 1【快速上手】 项目常用命令 vuepress dev [dir] 会启动一个开发服务器,以便让你在本地开发你的 VuePress 站点。vuepress build [dir] 会将你的 VuePress 站点构建成静态文件,以便你进行后…...
ClickHouse基础知识(四):ClickHouse 引擎详解
1. 表引擎的使用 表引擎是 ClickHouse 的一大特色。可以说, 表引擎决定了如何存储表的数据。包括: ➢ 数据的存储方式和位置,写到哪里以及从哪里读取数据。 默认存放在/var/lib/clickhouse/data ➢ 支持哪些查询以及如何支持。 ➢ 并发数…...
关于设计模式、Java基础面试题
前言 之前为了准备面试,收集整理了一些面试题。 本篇文章更新时间2023年12月27日。 最新的内容可以看我的原文:https://www.yuque.com/wfzx/ninzck/cbf0cxkrr6s1kniv 设计模式 单例共有几种写法? 细分起来就有9种:懒汉&#x…...
Python爱心光波完整代码
文章目录 环境需求完整代码详细分析环境需求 python3.11.4PyCharm Community Edition 2023.2.5pyinstaller6.2.0(可选,这个库用于打包,使程序没有python环境也可以运行,如果想发给好朋友的话需要这个库哦~)【注】 python环境搭建请见:https://want595.blog.csdn.net/arti…...
PowerShell Instal 一键部署gitea
gitea 前言 Gitea 是一个轻量级的 DevOps 平台软件。从开发计划到产品成型的整个软件生命周期,他都能够高效而轻松的帮助团队和开发者。包括 Git 托管、代码审查、团队协作、软件包注册和 CI/CD。它与 GitHub、Bitbucket 和 GitLab 等比较类似。 Gitea 最初是从 Gogs 分支而来…...
C语言——指针题目“指针探测器“
如果你觉得你指针学的自我感觉良好,甚至已经到达了炉火纯青的地步,不妨来试试这道题目? #include<stdio.h> int main() {char* c[] { "ENTER","NEW","POINT","FIRST" };char** cp[] { c 3…...
Hive讲课笔记:内部表与外部表
文章目录 一、导言二、内部表1.1 什么是内部表1.1.1 内部表的定义1.1.2 内部表的关键特性 1.2 创建与操作内部表1.2.1 创建并查看数据库1.2.2 在park数据库里创建student表1.2.3 在student表插入一条记录1.2.4 通过HDFS WebUI查看数据库与表 三、外部表2.1 什么是外部表2.2 创建…...
Docker本地部署开源浏览器Firefox并远程访问进行测试
文章目录 1. 部署Firefox2. 本地访问Firefox3. Linux安装Cpolar4. 配置Firefox公网地址5. 远程访问Firefox6. 固定Firefox公网地址7. 固定地址访问Firefox Firefox是一款免费开源的网页浏览器,由Mozilla基金会开发和维护。它是第一个成功挑战微软Internet Explorer浏…...
PHP:服务器端脚本语言的瑰宝
PHP(Hypertext Preprocessor)是一种广泛应用于服务器端编程的开源脚本语言,它以其简单易学、灵活性和强大的功能而成为Web开发的瑰宝。本文将深入介绍PHP的历史、特性、用途以及与生态系统的关系,为读者提供对这门语言全面的了解。…...
【MySQL】数据库并发控制:悲观锁与乐观锁的深入解析
🍎个人博客:个人主页 🏆个人专栏: 数 据 库 ⛳️ 功不唐捐,玉汝于成 目录 前言 正文 悲观锁(Pessimistic Locking): 乐观锁(Optimistic Locking): 总结&#x…...
作业--day38
1.定义一个Person类,包含私有成员,int *age,string &name,一个Stu类,包含私有成员double *score,Person p1,写出Person类和Stu类的特殊成员函数,并写一个Stu的show函数ÿ…...
pytest 的 fixture 固件机制
一、前置说明 固件(fixture)是一些函数,pytest 会在执行测试函数之前(或之后)加载运行它们。pytest 使用 fixture 固件机制来实现测试的前置和后置操作,可以方便地设置和共享测试环境。 二、操作步骤 1. 编写测试代码 atme/demos/demo_pytest_tutorials/test_pytest_…...
分布式技术之分布式计算Stream模式
文章目录 什么是 Stream?Stream 工作原理Storm 的工作原理 实时性任务主要是针对流数据的处理,对处理时延要求很高,通常需要有常驻服务进程,等待数据的随时到来随时处理,以保证低时延。处理流数据任务的计算模式&#…...
2023年12月GESP Python五级编程题真题解析
【五级编程题1】 【试题名称】:小杨的幸运数 【问题描述】 小杨认为,所有大于等于a的完全平方数都是他的超级幸运数。 小杨还认为,所有超级幸运数的倍数都是他的幸运数。自然地,小杨的所有超级幸运数也都是幸运数。 对于一个…...
golang循环变量捕获问题
在 Go 语言中,当在循环中启动协程(goroutine)时,如果在协程闭包中直接引用循环变量,可能会遇到一个常见的陷阱 - 循环变量捕获问题。让我详细解释一下: 问题背景 看这个代码片段: fo…...
大数据零基础学习day1之环境准备和大数据初步理解
学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...
BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南 在数字化营销时代,邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天,我们将深入解析邮件打开率、网站可用性、页面参与时…...
USB Over IP专用硬件的5个特点
USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中,从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备(如专用硬件设备),从而消除了直接物理连接的需要。USB over IP的…...
基于 TAPD 进行项目管理
起因 自己写了个小工具,仓库用的Github。之前在用markdown进行需求管理,现在随着功能的增加,感觉有点难以管理了,所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD,需要提供一个企业名新建一个项目&#…...
Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战
说明:这是一个机器学习实战项目(附带数据代码文档),如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下,风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...
LLMs 系列实操科普(1)
写在前面: 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容,原视频时长 ~130 分钟,以实操演示主流的一些 LLMs 的使用,由于涉及到实操,实际上并不适合以文字整理,但还是决定尽量整理一份笔…...
【Android】Android 开发 ADB 常用指令
查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...
实战三:开发网页端界面完成黑白视频转为彩色视频
一、需求描述 设计一个简单的视频上色应用,用户可以通过网页界面上传黑白视频,系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观,不需要了解技术细节。 效果图 二、实现思路 总体思路: 用户通过Gradio界面上…...
