当前位置: 首页 > news >正文

【socket网络编程】

socket网络编程

  • 主机字节序列和网络字节序列
  • 套接字地址结构
    • 通用socket地址结构
    • 专用的socket地址结构
    • IP地址转换函数
  • 网络编程接口
  • TCP编程流程
  • 代码举例
    • 服务器代码
    • 客户端
  • 服务器并发处理多个客户端
    • 多线程
    • 多进程

主机字节序列和网络字节序列

主机字节序列分为大端模式和小端模式,不同主机可能采用的不相同。大端模式是指一个整数的高字节位存储在内存的低地址处,低位字节存储在内存的高地址处。小端则是刚好相反。在两台使用不同字节序的主机之间传递数据时,可能会出现冲突。所以,在将数据发送到网络时 规定整形数据使用大端字节序,所以也把 大端字节序成为网络字节序列。对方接收到数据后,可以根据自己的字节序进行转换。
linux提供了四个函数来完成主机字节序和网络字节序的转换。

#include <netinet/in.h>
uint32_t htonl(uint32_t hostlong);//长整型的主机字节序转网络字节序
uint32_t ntohl(uint32_t netlong);//长整型的网络字节序转主机字节序
uint16_t htons(uint16_t hostshort);//短整型的主机字节序转网络字节序
uint16_t ntohs(uint16_t netshort);//短整型的网络字节序列转主机字节序列 

套接字地址结构

通用socket地址结构

socket网络变成接口中表示socket地址的是结构体sockaddr,定义如下:

#include<bits/socket.h>
struct sockaddr{sa_family_t sa_family;char sa_data[14];
}

专用的socket地址结构

TCP/IP 协议族有 sockaddr_in 和 sockaddr_in6 两个专用 socket 地址结构体,它们分别用于 IPV4 和 IPV6。

1. //
2. //sin_family: 地址族 AF_INET
3. //sin_port: 端口号,需要用网络字节序表示
4. //sin_addr: IPV4 地址结构:s_addr 以网络字节序表示 IPV4 地址
5. //
6. struct in_addr
7. {
8. u_int32_t s_addr;
9. };
11.
10. struct sockaddr_in
11. {
12. sa_family_t sin_family;
13. 15. u_int16_t sin_port;
16. struct in_addr sin_addr;
17. };
18.
19. struct in6_addr
20. {
21. unsigned char sa_addr[16]; // IPV6 地址,要用网络字节序表示
22. };
23.
24. struct sockaddr_in6
25. {
26. sa_family_t sin6_family; // 地址族:AF_INET6
27. u_inet16_t sin6_port; // 端口号:用网络字节序表示
28. u_int32_t sin6_flowinfo; // 流信息,应设置为 0
29. struct in6_addr sin6_addr; // IPV6 地址结构体
30. u_int32_t sin6_scope_id; // scope ID,尚处于试验阶段
31. };

IP地址转换函数

通常,人们习惯用点分十进制字符串表示 IPV4 地址,但编程中我们需要先把它们转化为整数方能使用,下面函数可用于点分十进制字符串表示的 IPV4 地址和网络字节序整数表示的 IPV4 地址之间的转换。

#include<arpa/inet.h>
in_addr_t inet_addr(const char* cp);//字符串表示的IPV4地址转化位网络字节序
char* inet_ntoa(struct in_addr in);//IPV4地址的网络字节序转化为字符串表示

网络编程接口

#include<sys/types.h>
#inlcude<sys/socket.h>
int socket(int domain, int type, int protocol);//创建套接字,成功返回套接字文件描述符,失败返回-1
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)//bind()将 sockfd 与一个 socket 地址绑定,成功返回 0,失败返回-1
int listen(int sockfd, int backlog);//创建一个监听队列等待客户连接。
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);//accept()从 listen 监听队列中接收一个连接,成功返回一个新的连接 socket,唯一标识链接成功失败。失败返回-1int connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen);//客户端通过此系统来主动与服务器产生链接,成功返回0,失败返回-1.int close(int sockfd);//关闭一个连接ssize_t recv(int sockfd, void *buff, size_t len, int flags);//recv()读取 sockfd 上的数据,buff 和 len 参数分别指定读缓冲区的位置和大小ssize_t send(int sockfd, const void *buff, size_t len, int flags);// send()往 socket 上写入数据,buff 和 len 参数分别指定写缓冲区的位置和数据长度ssize_t recvfrom(int sockfd, void *buff, size_t len, int flags,struct sockaddr* src_addr, socklen_t *addrlen);//读取 sockfd 上的数据,buff 和 len 参数分别指定读缓冲区的位置和大小
ssize_t sendto(int sockfd, void *buff, size_t len, int flags,struct sockaddr* dest_addr, socklen_t addrlen);// 	sendto()往 socket 上写入数据,buff 和 len 参数分别指定写缓冲区的位置和数据长度

TCP编程流程

TCP提供的是面向连接的可靠的字节流服务。TCP的服务器端和客户端编程流程如下图:在这里插入图片描述
socket()方法是用来创建一个套接字,有了套接字就可以通过网络进行数据的收发。
bind()方法是用来指定套接字使用的 IP 地址和端口。
listen()方法是用来创建监听队列。
accept()处理存放在 listen 创建的已完成三次握手的队列中的连接。
connect()方法一般由客户端程序执行,需要指定连接的服务器端的 IP 地址和端口。该方法执行后,会进行三次握手, 建立连接。
send()方法用来向 TCP 连接的对端发送数据。send()执行成功,只能说明将数据成功写入
到发送端的发送缓冲区中,并不能说明数据已经发送到了对端。send()的返回值为实际写入到发送缓冲区中的数据长度。
recv()方法用来接收 TCP 连接的对端发送来的数据。recv()从本端的接收缓冲区中读取数据,如果接收缓冲区中没有数据,则 recv()方法会阻塞。返回值是实际读到的字节数,如果recv()返回值为 0, 说明对方已经关闭了 TCP 连接。
close()方法用来关闭 TCP 连接。此时,会进行四次挥手。

代码举例

服务器代码

在这里插入图片描述
在这里插入图片描述

客户端

在这里插入图片描述

服务器并发处理多个客户端

多线程

在这里插入图片描述
在这里插入图片描述
客户端代码同上相同

多进程

在这里插入图片描述
在这里插入图片描述

http://www.lryc.cn/news/25928.html

相关文章:

  • 【验证码逆向专栏】某验三代、四代一键通过模式逆向分析
  • 《MySql学习》 MySQL的 加锁规则
  • 软件测试(linux命令篇-01文件操作命令)
  • Code Virtualizer 3.1.4 Crack
  • Torch同时训练多个模型
  • LCR数字电桥软件下载安装教程
  • C++模板写法详解
  • 【备战面试】每日10道面试题打卡-Day2
  • “数字档案室测评”相关参考依据梳理
  • android 动态加载jar包
  • JAVA版B2B2C商城源码多商户入驻商城
  • 测试人员如何在测试环境数据库批量生成测试数据?方案分享
  • 【el】表单
  • 【Flutter入门到进阶】Flutter基础篇---布局
  • python海龟绘图
  • 【计算机网络】数据链路层
  • 使用groovy代码方式解开gradle配置文件神秘面纱
  • kafka入门到实战二(使用docker搭建kafka集群)
  • 【简化开发】lombok的使用、编译后的代码及源码
  • 在线就能用的主图设计素材,免费分享!
  • 【测绘程序设计】——计算卫星位置
  • 山东双软认证的基本条件
  • TPM 2.0实例探索3 —— LUKS磁盘加密(4)
  • Linux连接RDP远程服务工具集记录
  • 离散事件动态系统
  • 无线WiFi安全渗透与攻防(二)之打造专属字典
  • 拥抱 Spring 全新 OAuth 解决方案
  • 前端开发与vscode开发工具介绍
  • C++---最长上升子序列模型---友好城市(每日一道算法2023.3.2)
  • maven高级知识。