首页 > 编程语言 >网络编程-Socket通信

网络编程-Socket通信

时间:2024-08-26 19:48:11浏览次数:10  
标签:addr int 编程 通信 对象 地址 sockfd Socket

Socket通信

1、什么是套接字

​ Socket是封装了TCP/IP协议簇的系统API接口,这使得程序员无需关注协议本身,直接使用socket提供的接口与不同主机间的进程互联通信。
​ 目前市面上主流的操作系统都采用这套机制进制网络通信,所以不同种类的操作系统,使用不同的编程语言,只要调用操作系统提供的Socket接口,都能进行网络通信。

2、基于TCP协议的Socket编程模型

被连接者需要完成的任务(服务端)

1、创建socket内核对象,内核创建完成后会返回它的描述符(该描述只是为了完成连接,三次握手)
2、准备本机地址(ip地址+端口号)
3、绑定(把本机地址与socket对象进行绑定)
4、开启监听,并设置排队的队列长度
5、等待连接,连接成功后,内核会再返回一个连接成功的Socket描述符,专门用来通信
for (;;) {
	6、接收请求
	7、返回结果
}
8、关闭通信的Socket对象
9、关闭连接的Socket对象

连接者需要完成的任务(客户端)

1、创建socket内核对象,内核创建完成后会返回它的描述符
2、准备被连接者的地址(ip地址+端口号)
3、发起连接,使用Socket+地址(ip地址+端口号)发起连接请求
for (;;) {
	4、发送请求
	5、接收结果
}
6、关闭Socket对象

3、TCP通信需要使用Socket接口

/**
 * 功能: 创建Socket对象
 * @domain:
 *    AF_UNIX, AF_LOCAL   采用本地socket文件进行通信,如果用它则只能本机上的两个进程进行通信
 *	  AF_INET             IPv4地址
 *	  AF_INET6   			IPv6地址
 * @type:
 *    SOCK_STREAM	数据流	TCP
 *    SOCK_DGRAM 报文 UDP
 * @protocol:
 *    特殊通信协议,写0即可
 * 返回值:
 *    成功则返回Socket对象描述符,失败返回-1。
*/
int socket(int domain, int type, int protocol);

// 基本地址类型,它是socket系列接口的表面参数,而实际使用的是sockaddr_un或sockaddr_in,我们需要把sockaddr_in强制转换成sockaddr类型。
struct sockaddr_in  {
    sa_family_t sin_family;		// 地址类型,与domain保持一致即可
    in_port_t sin_port;			// 端口号,网络字节序的2字节整数
    struct in_addr sin_addr.s_addr;	// IP地址,网络字节序的4字节整数
};

/**
 * 功能: 绑定Socket对象与通信地址
 * @sockfd: Socket对象描述符
 * @addr: 通信地址,实际提供可能是sockaddr_un或sockaddr_in,需要对它们进行强制转换
 * @addrlen: addr结构体的字节数
 * 返回值: 成功返回0,失败返回-1
*/
int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);

/**
 * 功能: 开启Socket对象的监听
 * sockfd: Socket地址描述符
 * backlog: 备胎的数量
*/
int listen(int sockfd, int backlog);
    
/**
 * 功能: 等待连接,没有成功连接之前,会进入阻塞状态
 * @sockfd: Socket对象描述符
 * @addr: 用于存储连接者的通信地址
 * @addrlen: 既是输入(告诉accetp接口,addr结构体的字节数),也是输出(实际接收到的addr结构的字节数)
 * 返回值: 建立连接的,能够通信的Socket对象描述符,失败返回-1
*/
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
    
/**
 * 功能: 让sockfd对象向addr地址发起连接
 * @sockfd: Socket对象描述符
 * @addr: 连接目标的地址
 * @addrlen: addr结构体的字节数
 * 返回值: 成功返回0,失败返回-1
*/
int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);

/**
 * 功能: 从Socket对象读接收干字节
 * @sockfd: Socket对象描述符
 * @buf: 接收数据的内存块首地址
 * @len: buf的字节数
 * @flags: 是否阻塞,写0即可
 * 返回值: 成功接收到了多少个字节,失败返回-1
*/  
ssize_t recv(int sockfd, void *buf, size_t len, int flags);

/**
 * 功能: 通过Socket对象发送若干字节
 * @sockfd: Socket对象描述符
 * @buf: 要发送的内存块首地址
 * @len: 要发送的字节数
 * @flags: 是否阻塞,写0即可
 * 返回值: 成功发送了多少个字节,失败返回-1
*/
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
    
/**
 * 功能: 关闭fd描述所代表的内核对象
*/
int close(int fd);

/**
 * 功能: 把本地字节序的 unsigned short 类型的数据转换网络字节序
*/
uint16_t htons(uint16_t hostshort);
    
/**
 * 功能: 把字符串格式 点分十进制的ip地址 转换成网络字节序的4字节ip地址
*/
in_addr_t inet_addr(const char *cp);

4、基于UDP协议的Socket编程模型

被接收者需要完成的任务(服务端)

1、创建socket内核对象,内核创建完成后会返回它的描述符
	type:SOCK_DGRAM
2、准备本机地址(ip地址+端口号)
3、绑定(把本机地址与socket对象进行绑定)
for (;;) {
	4、接收请求,同时接收发送者的地址
	5、返回结果,按发送者的地址进行返回
}
6、关闭Socket对象

发送者需要完成的任务

1、创建socket内核对象,内核创建完成后会返回它的描述符
	type:SOCK_DGRAM
2、准备接收者的地址(ip地址+端口号)
for (;;) {
	3、发送请求,根据接收者的地址发送数据
	4、接收结果,并接收返回者的地址
}
5、关闭Socket对象

5、UDP通信需要使用Socket接口

/**
 * 功能: UDP专用的数据发送函数。
 * @dest_addr: 收件人的地址。
 * @addrlen: 地址长度。
*/
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
                      const struct sockaddr *dest_addr, socklen_t addrlen);

/**
 * 功能: UDP专用的数据接收函数。
 * @src_addr: 发件人的地址,也是数据返回时的地址
 * @addrlen: 地址长度,既是输入也是输出
*/           
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
                        struct sockaddr *src_addr, socklen_t *addrlen);

6、UDP的连接操作

​ UPD协议底层是否需要连接操作,客户端但可以在Socket层面进行连接,连接后的Socket对象在后续的通信过程中就不再需要通信地址了。

7、本地Socket通信

​ 网络Socket通信是把网卡抽象成Socket文件配合TCP/IP协议簇,能够使当前进程与其它计算机的进程进行网络通信。
​ 本地Socket通信是在文件系统中创建Socket文件,能够使当前进程与本机的其它进程进行通信(IPC进程间通信)。
​ 使用sockaddr_un类型的通信地址,当调用socket对象与通信地址绑定时,会自动创建socket文件。

标签:addr,int,编程,通信,对象,地址,sockfd,Socket
From: https://www.cnblogs.com/sleeeeeping/p/18381523

相关文章

  • 【流式编程】Stream.of()用法解析及使用示例
    Stream.of()是Java8引入的StreamAPI中的一个静态方法,用于从给定的元素创建一个顺序流(SequentialStream)。这个方法非常灵活,允许你直接从一组元素中创建一个流,而不需要这些元素已经存在于某个集合或数组中。这对于快速创建和操作流非常有用。用法解析Stream.of()......
  • stm32之I2C通信协议
    文章目录前言一、I2C通信协议二、I2C硬件电路三、I2C时序基本单元3.1起始与终止信号3.2发送与接收一个字节3.3发送与接收应答四、I2C时序分析4.1指定地址写4.2当前地址读4.3指定地址读前言提示:本文主要用作在学习江科大自化协STM32入门教程后做的归纳总结笔......
  • Python 多线程编程技巧举例
    Python多线程(Multithreading)是一种编程技术,允许在同一程序中同时执行多个独立的逻辑流,即线程。每个线程都有自己的程序计数器、栈空间和局部变量,它们共享同一进程的全局变量、文件描述符和其他系统资源。线程是操作系统调度的基本单位,能够在单个进程中并发运行,从而实现任务......
  • UVM中的TLM(事务级建模)通信(2)
    上一篇介绍了UVM中利用TLM进行的一对一通信:UVM中的TLM(事务级建模)通信(1)-CSDN博客,除此之外,UVM还有两种特殊的端口:analysis_port和analysis_export,用于完成一对多的通信。1.analysis端口    这两种端口同样也是用于传递transaction,他们与put,get的区别是:   ......
  • 24. 网络编程
    osi七层协议 每层常见物理设备 OSI(OpenSystemsInterconnection)七层协议是由国际标准化组织(ISO)制定的一个网络模型,它将网络系统划分为七个层次。以下是各层的详细解释: ‌物理层(PhysicalLayer)‌:这是OSI模型的最低层或第一层。它负责在物理媒体上传输原始的比特流......
  • 世邦通信SPON IP网络对讲广播系统任意文件上传漏洞
    0x00漏洞编号暂无0x01危险等级高危0x02漏洞概述世邦通信SPONIP网络对讲广播系统采用领先的IPAudio™技术,将音频信号以数据包形式在局域网和广域网上进行传送,是一套纯数字传输系统。0x03漏洞详情漏洞类型:任意文件上传影响:上传恶意脚本简述:世邦通信SPONIP网络对讲广播......
  • 突破编程:深入理解C++中的组合模式
    突破编程:深入理解C++中的组合模式在C++及众多面向对象编程语言中,设计模式是解决问题的经典方案,它们帮助开发者在面对复杂系统设计时,能够遵循一套经过验证的最佳实践。组合模式(CompositePattern)是这些设计模式中的一种,它提供了一种将对象组合成树形结构以表示“部分-整体”......
  • CUDA编程07 - 卷积的优化
    一:概述        在接下来的几篇文章中,我们将讨论一组重要的并行计算模式。这些模式是许多并行算法的基础,这些算法出现在许多并行应用中。我们将从卷积开始,卷积是一种流行的数组操作,广泛应用于信号处理、数字录音、图像处理、视频处理和计算机视觉等领域。在这些应用领......
  • Javascript之函数式编程
    一、是什么函数式编程是一种"编程范式"(programmingparadigm),一种编写程序的方法论主要的编程范式有三种:命令式编程,声明式编程和函数式编程相比命令式编程,函数式编程更加强调程序执行的结果而非执行的过程,倡导利用若干简单的执行单元让计算结果不断渐进,逐层推导复杂的运算......
  • 【AI编程秘籍】Q-learning原理大揭秘!让AI学会自己做决策!
    ......