Socket编程TCP 基础

 一.什么是Socket(套接字)

        定义:就是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象。一个套接字就是网络上进程通信的一端,提供了应用层进程利用网络协议交换数据的机制。从所处的地位来讲,套接字上联应用进程,下联网络协议栈,是应用程序通过网络协议进行通信的接口,是应用程序与网络协议栈进行交互的接口。

        定义比较难理解,总之我们认为通过socket及各层协议我们可以实现网络通信。网络通信的本质就是不同主机上进程的通信,那么我们是如何通过socket定位到一个主机的进程的呢?答案是ip(定位网络上唯一台主机)+端口号(主机上唯一一个进程),通过socket绑定ip和端口号,我们可以定位网络上唯一一个进程。

二.认识TCP协议和UDP协议

TCP:

传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议,由IETF的RFC 793 [1]定义。

TCP旨在适应支持多网络应用的分层协议层次结构。 连接到不同但互连的计算机通信网络的主计算机中的成对进程之间依靠TCP提供可靠的通信服务。TCP假设它可以从较低级别的协议获得简单的,可能不可靠的数据报服务。 原则上,TCP应该能够在从硬线连接到分组交换或电路交换网络的各种通信系统之上操作。

我们主要理解以下TCP协议四个特点:

  •  传输层协议
  •  有连接
  •  可靠传输
  •  面向字节 

UDP: 

此外UDP协议也是传输层常用的协议,UDP是User Datagram Protocol的简称,中文名是用户数据报协议,是OSI参考模型中的传输层协议,它是一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务。

具有以下四个特定:

  • 传输层协议
  • 无连接
  • 不可靠传输
  • 面向数据报

对于UDP本文不主要讲解

三. TCP中socket常用API 的讲解 

1.sockaddr 结构

socket API 是一层抽象的网络编程接口,适用于各种底层网络协议,如 IPv4、IPv6,以及后面要讲的 UNIX Domain Socket. 然而, 各种网络协议的地址格式并不相同。简单了解就是,由于socket不仅能用于网络通信还能用于本地通信等,描述socket的地址格式应该不同。

主要有以下俩种格式:

第一种用于网络,第二种用于本地通信。

socket的地址在socket的多种API中我们都会用到,为了程序的通用性, 可以接收 IPv4, IPv6, 以及 UNIX Domain Socket 各种类型的 sockaddr 结构体指针做为参数, 因此我们采用一个 struct sockaddr *类型来接受各种参数(就类似于c++中的多态)。表示如下:

我们来了解网络通信需要的struct sockaddr_in的各种字段:

struct sockaddr_in {short            sin_family;    // 2 字节 ,地址族,e.g. AF_INET, AF_INET6unsigned short   sin_port;      // 2 字节 ,16位TCP/UDP 端口号 e.g. htons(3490),struct in_addr   sin_addr;      // 4 字节 ,32位IP地址char             sin_zero[8];   // 8 字节 ,不使用
};

 

  • sin_family主要用来定义是哪种地址族(地址族就是一个协议族所使用的地址集合,也是用宏来表示不同的地址族,这个宏的形式是AF开头,比如IP地址族为AF_INET,AF的意思是ADDRESS FAMILY)
  • sin_port主要用来保存端口号
  • sin_addr主要用来保存IP地址信息
  • sin_zero没有特殊含义

struct in_addr的内容如下:

struct in_addr {unsigned long s_addr; // 32位IPV4地址打印的时候可以调用inet_ntoa()函数将其转换为char *类型.
};

可以看出struct in-addr是用于存储IP的。

这里我们需要注意网络通信中的字节序是大端字节序,我们传入的ip和端口号需要从主机序列转换为网络序列。 

2.socket函数(创建socket)

 #include <sys/types.h>        #include <sys/socket.h>int socket(int domain, int type, int protocol);

  • 1.domain 参数: domain 参数指定套接字的协议族,常见的协议族有 AF_INET(IPv4)、AF_INET6(IPv6)和 AF_UNIX(本地套接字)等。前2个用于网络通信,最后一个用于本地通信。
  • 2.type 参数: type 参数指定套接字的类型,常见的类型有 SOCK_STREAM(流套接字/TCP 套接字)和 SOCK_DGRAM(数据报套接字/UDP套接字)等。
  • 3.protocol 参数:protocol 参数指定使用的协议,常见的协议有 IPPROTO_TCP(TCP 协议)和 IPPROTO_UDP(UDP 协议)等。如果指定为 0,则会根据 domain 和 type 参数自动选择协议。 
  • 4.返回值:socket()打开一个网络通讯端口,如果成功的话,就像 open()一样返回一个文件描述符;

3.bind函数(绑定ip和端口号)

 #include <sys/types.h>#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);

bind()函数的作用是将ip和端口号绑定到socket()函数创建的文件的文件描述符上。

在服务端需要我们手动绑定,客户端操作系统会自动帮我们绑定

第一个参数sockfd是我们需要绑定的文件描述符。第二个是地址,第三个是地址的长度。

bind()成功返回 0,失败返回-1。

4. listen函数(监听连接请求)

  #include <sys/types.h>          #include <sys/socket.h>int listen(int sockfd, int backlog);

第一个是socket文件描述符.

第二个参数backlog是侦听队列的长度。 在进程正在处理一个连接请求的时候,可能还存在其它的连接请求。因为TCP连接是一个过程,所以可能存在一种半连接的状态,有时由于同时尝试连接的用户过多,使得服务器进程无法快速地完成连接请求。如果这个情况出现了,服务器进程希望内核如何处理呢?内核会在自己的进程空间里维护一个队列以跟踪这些完成的连接但服务器进程还没有接手处理的连接(还没有调用accept函数的连接),这样的一个队列内核不可能让其任意大,所以必须有一个大小的上限。这个backlog告诉内核使用这个数值作为上限。

listen()成功返回 0,失败返回-1

5.accept函数(接受连接函数)

 #include <sys/types.h>          #include <sys/socket.h>int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

第一个参数还是表示文件描述符

第二个参数addr 是一个传出参数,accept()返回时传出客户端的地址和端口号, 如果给 addr 参数传 NULL,表示不关心客户端的地址;

 第三个参数addrlen 参数是一个传入传出参数(value-result argument), 传入的是调用者提 供的, 缓冲区 addr 的长度以避免缓冲区溢出问题, 传出的是客户端地址结构体的实 际长度(有可能没有占满调用者提供的缓冲区);

返回值是一个新的文件描述符,用新的文件描述符来进行信息的传输和接收。我们可以看做拉客的过程,第一个文件描述符主要用来门外拉客(监听和接受),第二个用于店内一对一服务客人(信息的传输和接收)

6.connect函数(连接函数客户端使用)

  #include <sys/types.h>        #include <sys/socket.h>int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);

客户端需要调用 connect()连接服务器;

 connect 和 bind 的参数形式一致, 区别在于 bind 的参数是自己的地址, 而 connect 的参数是对方的地址;

connect()成功返回 0,出错返回-1。

7.流程总结:

客户端:socket()---->accetp()(操作系统会自动调用bind())。

服务器端:socket()---->bind()---->listen()---->asscept()。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/403577.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C:每日一练:单身狗(2.0版本)

前言&#xff1a; 今天在刷题的时候突然看到一道题&#xff0c;疑似一位故题。仔细一看&#xff0c;欸&#xff01;这不是就是单身狗的升级版吗&#xff1f;我想那必须再安排一篇&#xff0c;不过由于本篇文章与上一篇单身狗文章所涉及的知识点基本相同&#xff0c;所以还请大…

政企单位如何选择适合规模的即时通讯软件?

政企单位在不同规模的组织结构中都面临着沟通和协作的挑战。为了提高工作效率和团队协作能力&#xff0c;选择适合规模的即时通讯软件至关重要。本文将为政企单位在选择适合规模的即时通讯软件时提供一些关键要素和指导&#xff0c;同时重点介绍WorkPlus作为一个可以迎合政企单…

谷歌的高级指令有哪些

今天会分享一些组合用法&#xff0c;这样就能节省许多时间可以放在跟进客户上面&#xff08;本文只介绍谷歌的搜索指令&#xff0c;并无推广&#xff09; part one 谷歌常用的搜索引擎指令&#xff1a; 1、Inurl&#xff0c;在网址中 2、Intext&#xff0c;在网页内容中 3、…

tcpdump入门——抓取三次握手数据包

1. 使用docker启动一个tcp应用 参考&#xff1a;https://blog.csdn.net/LONG_Yi_1994/article/details/141175526 2. 获取容器id docker ps |grep gochat 3. 获取容器的 PID 首先&#xff0c;你需要获得容器的进程 ID&#xff08;PID&#xff09;。可以使用 docker inspect…

遥感之常用各种指数总结大全

目前在遥感领域基本各种研究领域都会用到各种各样的指数&#xff0c;如水体指数&#xff0c;植被指数&#xff0c;农业长势指数&#xff0c;盐分指数&#xff0c;云指数&#xff0c;阴影指数&#xff0c;建筑物指数&#xff0c;水质指数&#xff0c;干旱指数等等众多。 本文对上…

【Web】巅峰极客2024 部分题解

目录 EncirclingGame GoldenHornKing php_online admin_Test EncirclingGame 玩赢游戏就行 GoldenHornKing 利用点在传入的app 可以打python内存马 /calc?calc_reqconfig.__init__.__globals__[__builtins__][exec](app.add_api_route("/flag",lambda:__i…

STM32通过I2C硬件读写MPU6050

目录 STM32通过I2C硬件读写MPU6050 1. STM32的I2C外设简介 2. STM32的I2C基本框图 3. STIM32硬件I2C主机发送流程 10位地址与7位地址的区别 7位主机发送的时序流程 7位主机接收的时序流程 4. STM32硬件与软件的波形对比 5. STM32配置硬件I2C外设流程 6. STM32的I2C.h…

Java Web|day6.MyBatis-Plus

MyBatisPlus 定义 mybatis-plus是一款Mybatis增强工具&#xff0c;用于简化开发&#xff0c;提高效率。 核心功能 注解 TableName 注解在类上&#xff0c;指定类和数据库表的映射关系。实体类的类名&#xff08;转成小写后&#xff09;和数据库表名相同时&#xff0c;可以不…

网络协议九 应用层 HTTPS

一 什么是 HTTPS 前面我们看到HTTP 有很多安全问题&#xff0c;因此引出了 对称加密 和 不对称加密。 那么这个对称加密和不对称加密&#xff0c;我们怎么和HTTP结合起来呢&#xff1f;HTTPS 就是弄好的 HTTP 和 加密结合的协议。 通过HTTP加密后的数据&#xff0c;整个传输过…

Fly Catcher:通过监测恶意信号来检测飞机欺骗

Fly Catcher 的开发者 Angelina Tsuboi 是一名飞行员、网络安全研究员和发明家。 她决定着手一个将这三个不同兴趣结合起来的项目&#xff0c;以解决航空雷达系统的一个重大问题。 ADS-B 系统最初用于基本的飞机定位和跟踪&#xff0c;Tsuboi 对该系统的网络安全方面进行了深…

Java语言程序设计——篇十四(1)

&#x1f33f;&#x1f33f;&#x1f33f;跟随博主脚步&#xff0c;从这里开始→博主主页&#x1f33f;&#x1f33f;&#x1f33f; 欢迎大家&#xff1a;这里是我的学习笔记、总结知识的地方&#xff0c;喜欢的话请三连&#xff0c;有问题可以私信&#x1f333;&#x1f333;&…

日撸Java三百行(day25:栈实现二叉树深度遍历之中序遍历)

目录 一、栈实现二叉树遍历的可行性 二、由递归推出栈如何实现中序遍历 1.左子树入栈 2.根结点出栈 3.右子树入栈 4.实例说明 三、代码实现 总结 一、栈实现二叉树遍历的可行性 在日撸Java三百行&#xff08;day16&#xff1a;递归&#xff09;中&#xff0c;我们讲过…

【C++11】入门基础

&#x1f525; 个人主页&#xff1a;大耳朵土土垚 &#x1f525; 所属专栏&#xff1a;C从入门至进阶 这里将会不定期更新有关C/C的内容&#xff0c;欢迎大家点赞&#xff0c;收藏&#xff0c;评论&#x1f973;&#x1f973;&#x1f389;&#x1f389;&#x1f389; 文章目录…

minikube 实践练习4 - 滚动更新

1. 应用版本更新 #查看image kubectl describe pods#设置应用的image为新版本 v1 -> v2 kubectl set image deployments/kubernetes-bootcamp kubernetes-bootcampdocker.io/jocatalin/kubernetes-bootcamp:v2#验证更新结果 export NODE_PORT"$(kubectl get services/…

糟糕界面集锦-控件篇11

GUI 的一个设计基本准则是&#xff1a;如果控件被禁用&#xff0c;那么就应该表现出来。这样不管是菜单项、命令按钮、列表框、下拉列表&#xff0c;我们只要一瞥就可以知道是否可用。奇怪的是为什么微软在按钮被禁用时不把它显示出来&#xff1f;这幅图片来自Office95 系列中的…

Redis操作--RedisTemplate(二)StringRedisTemplate

一、介绍 1、简介 由于存储在 Redis 中的 key 和 value 通常是很常见的 String 类型&#xff0c;Redis模块提供了 RedisConnection 和 RedisTemplate 的扩展&#xff0c;分是 StringRedisConnection 和 StringRedisTemplate&#xff0c;作为字符串操作的解决方案。 通过源码…

【区块链+金融服务】第一创业证券开发银行间报价 Dapp | FISCO BCOS应用案例

在银行间市场现券交易的过程中&#xff0c;通过银保监会发牌的代理机构进行报价交易&#xff0c;已解决无代理阶段存在的许多问题。 但是由于业务需要&#xff0c;使用以前模式进行报价交易的仍占有一定比例。 针对这一现状&#xff0c;第一创业证券基于 FISCO BCOS 区块链底层…

多种办公功能的WORD VBA程序

word的VBA办公助手 源代码 Option Explicit 需要引用 excel 16.0 库 所有内容仅供个人学习使用&#xff0c;严禁传播。1-公共变量-表格属性------------------------------------------------------------------------- Dim Hg% hg:行高 Const K1 0.1 Dim Flg_bh As Boolean …

专业技能——Redis常用命令和持久化策略,内存回收策略+主从模式,哨兵模式,集群模式+缓存穿透击穿雪崩

Redis 是一个开源&#xff08;BSD许可&#xff09;的&#xff0c;内存中的数据结构存储系统&#xff0c;它可以用作数据库、缓存和消息中间件。 它支持多种类型的数据结构&#xff0c;如 字符串&#xff08;strings&#xff09;&#xff0c;散列&#xff08;hashes&#xff09;…

Kali Linux-设置系统24小时时间制

文章目录 设置系统24小时时间制 设置系统24小时时间制 在Kali Linux中&#xff0c;如果系统时间不是以24小时制显示&#xff0c;你可以通过修改系统时间格式配置文件来调整为24小时制。以下是具体的操作步骤&#xff1a; 1.编辑/etc/locale.conf配置文件。 vim /etc/locale.c…