socket 套接字通信研究与讨论

这几天在学习套接字,借平台存个笔记~

套接字编程又称为网络编程,其基础配置需要配置端口号,IP地址,字节序等参数

socket是一种计算机之间,计算机与服务器之间通讯的方式,在传输层分为TCP,UDP协议;

socket的模型概要:

socket有一种理想化模型称为OSI模型,一共分为七层,分别为应用层,表示层,会话层,传输层,网络层,数据链路层,物理层;OSI模型是一个理想化模型,其架构思想完善,可以作为和好的参考;

而关于socket有一种常用模型,也就是TCP/IP模型,它和OSI模型相比更加精简,一共只有四层,分别为应用层(TELNET/FTP/HTTP/DNS/SMTP...) 、传输层(TCP/UDP) 、网络层(IP/ICMP/IGMP) 、网络接口和物理层(以太网/令牌环网/FDDI...);而整个数据封装过程则是层层跌进,一步步把数据封装成数据帧,从最原始的数据开始,在数据头部依次添加FTP头,TCP头,IP头,以太网头,以及最后在数据尾部增加CRC,完成一个以太网数据帧的封装,然后将这个数据帧通过路由器或者服务器发送到目标IP地址,再到接收端的令牌环网接口,接收端得到以太网数据帧后,转而形成他自己的令牌环网数据帧,然后对IP头,TCP头,FIP头进行比对,一层层把这些头取下,最终接收端收到发送端发来的消息,经过打印即可看到消息。

socket是插座的意思,是一个编程接口,是一个特殊的文件描述符,很多应用都依赖于socket的接口,如FTP/TELNET等;

socket存在的意义:

由于原始的IO操作就是打开文件,然后读写操作,进行增删改查移动等,最后关闭文件;

而socket文件操作,可以略过如此繁琐的操作,直接让两个程序进行交流,完成数据流的传输;

socket是一种独立于具体协议的网络编程接口,如果要放在OSI模型中,主要位于会话层和传输层之间;

  • 流式套接字 (SOCK_STREAM) TCP
    • 提供一个面向连接、可靠的数据传输服务,数据无差错、无重复、地发送并按顺序抵达。内设流量控制,避免数据流淹没前面的数据。数据被查看时字节流,无长度限制。
  • 数据报套接字(SOCK_DGRAM) UDP
    • 提供无连接服务,数据包以独立数据包形式被发送,不提供无差错保证,数据有可能丢失或重复到达,顺序发送可能会乱序接收
  • 原始套接字(SOCK_RAW)
    • 可以直接访问较低层次的协议例如 IP\ICMP。

IP地址

  • IP地址是网络中主机(电脑)的标识
  • 在网络中主机想要与其他机器通信就必须拥有一个自己的IP地址
  • IP地址为32位(IPV4)或者128位(IPV6)
  • 每一个数据包都必须携带目的地址IP和源IP地址,路由器依靠此信息为数据包选择最优路由(路线)

表示形式

点分形式:如 192.168.100.2 在传输过程中都会被转换为一个32位无符号的整数(二进制)

从本地字节序转为网络字节序

端口号 (用于区分计算机中某一个具体的程序)

  • 用于区分一台主机中接收到的数据包应该转交给哪一个进程进行处理。
  • TCP端口号与UDP端口号是相互独立的
  • 端口号一般由IANA(Internet Assigned Numbers Authority) 统一管理
  • 众所周知端口: 1 - 1023 (1-25之间为众所周知端口 , 256 - 1023 为UNIX系统占用)
    • 何为总所周知端口其实就是早已固定号的端口比如80端口分配给WWW服务,21端口分配给FTP服务等
  • 注册端口: 1024 -49151 分配给进程或者应用。这些端口号在还没有被服务器资源占用时,可以由用户的APP动态注册获得。
  • 动态端口号:49152 - 65535 被称为动态端口号他一般不固定分配某种服务而是动态分配的。一般可以使用 65000 以上的就可以随便用

字节序

不同的CPU 主机中,内存存储多个字节的序列分为两种,这个称为主机字节序

  • 小端序(Little-Endian)
    • 低序(低有效位)存储在低地址(起始地址),Intel\AMD 等采用的方式
  • 大端序(Big-Endian)
    • 高序(高有效位)存储在低地址 ARM采用的存储方式

为了避免在不同的处理器中收到的数据出现字节序带来的问题,因此网络中传输的数据必须按照网络字节序来处理,也就是大端序。发送者在发送数据前必须先转换为网络字节序,而接收者需要在收到网络中的数据时再转换为自己合适的主机字节序。

例如:0x12345678

在小端序中存放时:

12 34 56 78

高地址 --------- 低地址

在大端序中存放则相反

78 56 34 12

高地址 --------- 低地址

字节序转换API :

端口号的转换:
头文件:
    #include <arpa/inet.h>

函数原型:
       uint32_t htonl(uint32_t hostlong);  // 主机字节序到网络字节序 无符号长整型

       uint16_t htons(uint16_t hostshort);// 主机字节序到网络字节序 无符号短整型 

       uint32_t ntohl(uint32_t netlong); // 网络字节序转为主机字节序 无符号长整型

       uint16_t ntohs(uint16_t netshort); // 网络字节序转为主机字节序 无符号短整型 
tonl(uint32_t hostlong);  // 主机字节序到网络字节序 无符号长整型


IP地址转换:
    头文件:
       #include <sys/socket.h>
       #include <netinet/in.h>
       #include <arpa/inet.h>
       
函数原型:
        // 把cp指向的字符串转换为32位的网络字节序的二进制值存于inp中
        //  cp 点分十进制的网络地址的字符串 (IP地址)
       int inet_aton(const char *cp, struct in_addr *inp);
        
        // 把cp指向的字符串转换为32位的网络字节序的二进制值并返回
       in_addr_t inet_addr(const char *cp);
       in_addr_t inet_network(const char *cp);
        
        // 把in中的32位网络字节序的二进制地址转换为点分十进制的字符串
       char *inet_ntoa(struct in_addr in);

注意:

我们发送的内容是在表示层的协议中自动转换为网络字节序或者从网络字节序转换为主机字节序。但是IP地址以及端口号需要我们手动来设置并转换。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值