网络编程套接字概念(前提)

  • IP地址,端口号,网络字节序
  • socket api的基本用法
  • 实现一个简单的UDP客户端/服务器
  • 实现一个简单的TCP客户端/服务器(单链接版本,多进程版本,多线程版本)
  • TCP服务器建立连接,发送数据,断开连接的原理(即三次握手,四次挥手)

                                                  IP地址                                                    

1.IP地址分两部分:网络号和主机号

2.IP地址用来标志互联网的唯一一台主机,也就是说给互联网上的每一个主机(或路由器)的每一个接口分配一个在全世界范围内是唯一的32位标识符

3.通常来说,为了便于使用,我们采用点分十进制记法


4.在IP数据报报头,,有两个IP地址,分别是源地址IP地址和目的IP地址

                                                            端口号                                                    

端口号是属于传输层协议的内容

  • 端口号是一个2字节16位的整数; 
  • 端口号⽤用来标识一个进程, 告诉操作系统, 当前的这个数据要交给哪一个进程来处理; 
  • IP地址 + 端口号能够标识网络上的某一台主机的某一个进程(也就是我们所说的套接字
  • 一个端口号只能被一个进程占用.
  • 一个进程可以绑定多个端口号,但是一个端口号不能被多个进程绑定
  • 端口号不是每个进程都必须有,只有进程需要网络通信时才需要,但是PID是每个进程都有的

                                                            网络字节序                                                    

1.在传输层里面,有两个重要的协议:TCP协议和UDP协议(具体内容我们后面说,这里只说它们的特点)

TCP协议的五个特点

  • TCP是面向连接的运输层协议
  • 每一条TCP连接只能有两个端点,每一条TCP连接只能是点对点的(一对一)
  • TCP提供可靠交付的服务
  • TCP是全双工通信
  • 面向字节流

UDP协议的6个特点

  • 无连接的,即发送数据前不需要建立连接
  • 尽最大努力交付,即不保证可靠交付 
  • 面向报文的
  • 没有拥塞控制
  • 支持一对一,一对多、多对一、多对多的交互通信
  • 首部开销小,只有8个字节·   

2.我们已经知道,内存中的多字节数据相对于内存地址有大端和小端之分, 磁盘文件中的多字节数据相对于文件 中的偏移地址也有大端小端之分, 网络数据流同样有大端小端之分. 那么如何定义网络数据流的地址呢? 

  • 发送主机通常将发送缓冲区中的数据按内存地址从低到高的顺序发出; 
  • 接收主机把从网络上接到的字节依次保存在接收缓冲区中,也是按内存地址从低到高的顺序保存; 
  • 因此,网络数据流的地址应这样规定:先发出的数据是低地址,后发出的数据是高地址. 
  • TCP/IP协议规定,网络数据流应采用大端字节序,即低地址高字节.
  • 不管这台主机是大端机还是小端机, 都会按照这个TCP/IP规定的网络字节序来发送/接收数据; 
  • 如果当前发送主机是小端, 就需要先将数据转成大端; 否则就忽略, 直接发送即

3.调用库函数实现网络字节序和主机字节序的转换

  • 这些函数名很好记,h表示host,n表⽰示network,l表⽰示32位长整数,s表示16位短整数。 
  • 例如htonl表示将32位的长整数从主机字节序转换为网络字节序,例如将IP地址转换后准备发送。 
  • 如果主机是小端字节序,这些函数将参数做相应的大小端转换然后返回; 
  • 如果主机是大端字节序,这些 函数不做转换,将参数原封不动地返回。 

                                                            套接字                                                    

                                                      套接字socket = (IP地址:端口号)

1.socket常见API

// 创建 socket ⽂文件描述符 (TCP/UDP, 客户端 + 服务器) 
int socket(int domain, int type, int protocol);

// 绑定端⼝口号 (TCP/UDP, 服务器)      int bind(int socket, const struct sockaddr *address,  socklen_t address_len);

// 开始监听socket (TCP, 服务器)
 int listen(int socket, int backlog);

// 接收请求 (TCP, 服务器) 
int accept(int socket, struct sockaddr* address, socklen_t* address_len);

// 建⽴立连接 (TCP, 客户端)
 int connect(int sockfd, const struct sockaddr *addr,  socklen_t addrlen);

2.sockaddr结构

socket API是一层抽象的网络编程接口,适用于各种底层的网络协议,如IPv4、IPv6,但是各种网络协议的地址格式并不相同

  • IPv4和IPv6的地址格式定义在netinet/in.h中,IPv4地址⽤用sockaddr_in结构体表⽰示,包括16位地址类 型, 16位端⼝口号和32位IP地址. 
  • IPv4、IPv6地址类型分别定义为常数AF_INET、AF_INET6. 这样,只要取得某种sockaddr结构体的 ⾸首地址,不需要知道具体是哪种类型的sockaddr结构体,就可以根据地址类型字段确定结构体中的内 容. 
  • socket API可以都⽤用struct sockaddr *类型表⽰示, 在使⽤用的时候需要强制转化成sockaddr_in; 这样的 好处是程序的通⽤用性, 可以接收IPv4, IPv6, 以及UNIX Domain Socket各种类型的sockaddr结构体 指针做为参数; 


3.sockaddr_in 结构


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

4.in_addr结构

 

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值