【Linux】Socket网络编程

Socket编程基础

理解源网络通信本质

进程是人的代表,只要把数据交给进程,人就相当于拿到了数据,在整个网络传输过程中,数据传输并不是目的而是一种手段,最终目的也是把传输的数据交给上层进程被人所看到。

在简化理解:我们所讲的网络之间的通信,可以是主机之间的通信,单最终目的是把数据交给上层进程,所以网络通信的本质也是进程之间的通信(其原理也是让两个进程看到同一份资源)。

认识端口号

数据从网络中传输到目的ip主机上后,经过一层层解包分用,最后到达传输层,然后交给上层应用层的应用进程,但又由于上层应用进程特别多无法辨别到底是把数据交给哪个进程,所以我们引入端口号,来唯一标识一台目的ip主机上的唯一一个进程。

至此:我们可以理解全网唯一的一个网络进程(socket)可以用IP+端口号(port)来进行标识。

端口号的划分

0-1023:知名端口号,比如一些HTTP(80),FTP(21,20),ssh(22)等都是固定的。

1024-65535:可以自动分配的端口号。

进程号&端口号

端口号和进程号都可以标识网络中具体的一个进程,道理上讲我们是可以直接用进程号pid去表示一个确定的进程,但我们又引出了端口号去表示网络唯一进程,这是因为进程号pid属于系统概念,如果用进程号在网络通信中来表示唯一进程,这样做只会让系统管理和网络管理强耦合,引出端口号是为了让系统管理和网络管理进行解耦合。

源端口&目的端口

**源端口:**来确定源主机哪个进程发送的数据。

**目的端口:**来确定发送数据是发送给哪个进程的。

理解socket

我们把IP+port叫做socket(套接字)

IP:网络中确定的唯一的一台主机。

port:网络中确定主机的唯一的一个网络进程。

TCP协议&UDP协议

这里只了解一下各自协议特性,方便写代码,后续会详细介绍。

|---------|----------|
| TCP | UDP |
| 有连接 | 无连接 |
| 可靠的数据传输 | 不可靠的数据传输 |
| 面向字节流 | 面向数据报 |
| 传输层协议 | 传输层协议 |

这里的可靠与不可靠是中兴词,是根据丢包后是否重发决定的。

可靠:需要重新发包意味着做更多工作,实现复杂,占用资源多,但数据传输有保障。

不可靠:实现简单,占用资源少,但数据传输没保障。

所以对于可不可靠:各有各的优缺点,各有各的实现场景。

网络字节序

内存中的多字节数据相对于内存地址有大端和小端之分, 磁盘文件中的多字节数据相对于文件中的
偏移地址也有大端小端之分, 网络数据流同样有大端小端之分。

TCP/IP 协议规定: 网络数据流应采用大端字节序 , 即低地址高字节。
不管这台主机是大端机还是小端机 , 都会按照这个 TCP/IP 规定的网络字节序来发送/ 接收数据 ;
如果当前发送主机是小端 , 就需要先将数据转成大端 ; 否则就忽略 , 直接发送即可;

相关字节序转换系统调用接口

为使网络程序具有可移植性,使同样的 C 代码在大端和小端计算机上编译后都能正常运行,可以调用以下库函数做网络字节序和主机字节序的转换。

h: 主机(host),n:网络(network),l:(32位),s:(16位)

Socket编程接口

常见API

int socket(int domain, int type, int protocol);

创建一个通信的一端,打开网络文件,socket

domain:本地或网络通信 AF_INET:网络通信

type:创建tocket类型 sock_DGRAM //无连接不可靠

protocol:0前两个已经证明时udp

// 创建成功 返回 socket 文件描述符 (TCP/UDP, 客户端 + 服务器)
int bind(int socket, const struct sockaddr *address,socklen_t address_len);

// 绑定端口号 (TCP/UDP, 服务器)
int listen(int socket, int backlog);

// 开始监听 socket (TCP, 服务器)
int accept(int socket, struct sockaddr* address,socklen_t* address_len);

// 接收请求 (TCP, 服务器)
int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);

// 建立连接 (TCP, 客户端)
bzero(&local,sizeof(lockl));//结构体数据清0

inet_addr: (IP划分)点分十进制化为4字节+网络字节序

eg:192.1.1.1--->192 1 1 1
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen);

sockfd:套接字fd

buf:自定义缓冲区

flags:阻塞式IO如果如果没收到消息,该函数就阻塞等待。

src_addr/addrlen:获取客户端进程
sendto:(同上)

sockaddr****结构


socket API 可以都用 struct sockaddr * 类型表示 , 在使用的时候需要强制转化成sockaddr_in; 这样的好处是程序的通用性 , 可以接收 IPv4, IPv6, 以及 UNIX DomainSocket 各种类型的 sockaddr 结构体指针做为参数。
比如:struct sockaddr_in位网络通信,struct sockaddr_un为本地通信,我们在使用时需要显示实现,但是在使用相关接口时可以都强转为struct sockaddr*类型。这样做可以让os自动区分是网络通信还是本地通信。
常用的两种通信方式

AF_INET:网络通信 , AF_UNIX:域间通信(本地通信)

sockaddr_in****结构


虽然 socket api 的接口是 sockaddr, 但是我们真正在基于 IPv4 编程时 , 使用的数据结构是sockaddr_in; 这个结构里主要有三部分信息 : 地址类型 , 端口号 , IP 地址。
in_addr 结构

in_addr 用来表示一个 IPv4 的 IP 地址, 其实就是一个 32 位的整数 ;

Socket编程UDP

V1版本 --echo server

简单的回显客户端/服务器端代码,简单的进行通信。

相关项目代码

V2版本 --DictServer

在V1基础上实现一个简单的英汉互译词典。

相关推荐
wanhengidc2 小时前
云手机 高振畅玩不踩坑
运维·服务器·安全·web安全·智能手机
有谁看见我的剑了?2 小时前
linux 添加硬盘后系统识别不到硬盘处理
linux·运维·服务器
易连EDI—EasyLink2 小时前
易连EDI–EasyLink实现OCR智能数据采集
网络·人工智能·安全·汽车·ocr·edi
@insist1233 小时前
信息安全工程师考点精讲:身份认证核心原理与分类体系(上篇)
大数据·网络·分类·信息安全工程师·软件水平考试
SmartRadio3 小时前
ESP32-S3 双模式切换实现:兼顾手机_路由器连接与WiFi长距离通信
开发语言·网络·智能手机·esp32·长距离wifi
_.Switch3 小时前
东方财富股票数据JS逆向:secids字段和AES加密实战
开发语言·前端·javascript·网络·爬虫·python·ecmascript
yc_12244 小时前
用 Visual Studio 远程调试 Linux:从零到流畅的完整指南
linux·ide·visual studio
计算机安禾4 小时前
【Linux从入门到精通】第31篇:防火墙漫谈——iptables与firewalld防护指南
linux·运维·php
下一页盛夏花开4 小时前
ubuntu 20中安装QT以后出现红色空心断点
linux·运维·ubuntu
金色光环4 小时前
FreeModbus释放底层的 TCP 监听端口
服务器·网络·tcp/ip