我所不知道的TCP Socket编程(一)-简介+创建套接字

来源:互联网 发布:外勤365破解软件 编辑:程序博客网 时间:2024/05/13 19:04

Socket编程:

     

     套接字(Socket)连接起了数字世界;

     

     定义:

     源IP地址和目的IP地址以及源端口号和目的端口号的组合称为套接字。其用于标识客户端请求的服务器和服务。它是网络通信过程中端点的抽象表示,包含进行网络通信必需的五种信息:连接使用的协议,本地主机的IP地址,本地进程的协议端口,远地主机的IP地址,远地进程的协议端口。


     多个TCP连接或多个应用程序进程可能需要通过同一个TCP协议端口传输数据。为了区别不同的应用程序进程和连接,计算机操作系统为应用程序与TCP/IP协议交互提供了套接字(Socket)接口。应用层可以和传输层通过Socket接口,区分来自不同应用程序进程或网络连接的通信,实现数据传输的并发服务。
    

     初始印象:

     网络编程:一组特定的套接字编程API;

     使用之后记得关闭,否则会一直处于打开状态;

     每一次读取web页面时,就是在使用套接字;

     

     三个部分的内容:

     1)套接字编程的基础知识:创建套接字,链接套接字,共享套接字;

     2)阐述套接字编程的高级主题;

     3)实践运用;

     

     Berkeley套接字API:

     Berkeley套接字API最先与1983年出现在BSD操作系统4.2版本中;该操作系统是当时刚刚提出的TCP的首个实现;

     你可以在无需了解底层协议的情况下使用套接字;

     

     Berkeley套接字API是一种编程API,运作在实际的协议实现之上,关注的是链接两个端点(endpoint)共享数据,而非处理分组和序列号;

     

     基于C语言实现,几乎所有用C编写的现代编程语言都会包含它的底层次接口;

     

     netcat:

     netcat(在终端下通常是nc)是一个Unix工具,可以用于创建TCP(以及UDP)链接并进行监听;

     

一:建立套接字

     domin:AF_INET 特别指代IPv4版本的套接字;(还有其他的好多,比如IPv6)

     type:STREAM 类型是流,表示使用数据流进行通讯,该功能由TCP提供;(还可以是数据报类型DGRAM datagram的缩写,则表示UDP套接字);套接字的类型用来告诉内核需要创建什么样的套接字;

     

     基于域和类型可以创建一个套接字;

     比如我们可以创建第一个套接字:socket = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM)

     

     什么是端点:

     

     首先学习一下IPv4和寻址:

     在两个套接字直接通讯,需要知道如何找到对方;

     套接字使用IP地址将消息指向特定的主机;主机由唯一的IP地址来标识(以打电话来类比,IP地址就是主机的“电话号码”);

     

     如果是IPv4的地址:192.168.0.1,它是由点号链接的4个小于等于255的数字;

     配置了IP地址的主机可以同样向另一台同样配置了IP地址的主机发送数据;

     

     IP地址电话簿:

     DNS是一个用来将主机名映射到IP地址的系统,有了它就无需记忆主机的地址,不过得记住他的名字;随后可以让DNS将主机名解析成地址,即便地址发生了变动,主机名总是能将你引向正确的位置;

          

     环回地址:


     IP地址未必总是指向远端主机,尤其是在研发阶段,你通常需要连接自己本地主机上的套接字;

     多数系统都定义了环回接口(loopback interface);和网卡接口不同,这是一个与硬件无关、完全虚拟的接口;

     发送到环回接口上的数据立即会在同一个接口上被接收,配合环回接口就可以将网络搭建在本地主机中;

     

     环回接口对应的主机名是localhost,对应的IP地址通常是127.0.0.1,这些都定义在系统的hosts文件中;(浏览器中输入localhost It works!)

          

     IPv6:

     

     IPv6是区别于IPv4的另一种寻址方案;为啥要两种,因为IPv4已经用完了;

     IPv4由4组数字组成,各自范围是0~255,每组数字可以由8位二进制数字表示,合计32位二进制,这意味着有2^32或43亿个地址,无奈何,他枯竭了;

     IPv6采用了一种不同的格式,可以拥有天文数字级别的独立IP地址;

     不过大部分时候不用我们手动输入这些地址,无论使用哪种寻址方案,结果都一样;

          

     端口:

     

     端口而言,一个比较重要的方面是端口号;以电话的例子来说,拨电话时需要先拨电话号,再拨分机号;端口号就是套接字端点的“分机号”;

     对于每个套接字而言,IP地址和端口号的组合必须是唯一的,所以在同一个侦听端口上可以有两个套接字,一个使用IPv4地址,一个使用IPv6地址(但是这两个套接字不能都使用同一个IPv4地址);

     

     若没有端口号,一台主机一次只能支持一个套接字(将每个活动套接字与特定的端口号结合起来,主机便可以同时支持上千个套接字);

     

     我该使用哪个端口号?

     DNS没法解决这个问题,可以借助已经明确定义的端口号列表;

     如,http默认在80端口上进行通信,FTP的端口是21(实际上又一个组织负责维护这个列表,之后会介绍更多);(www.iana.org)

          

     创建第二个套接字:

     

     socket = Socket.new(:INET6, :STREAM)//Ruby的一种写法抽象,当前创建的套接字,还不能同其他套接字交换数据;

     

     在下才疏学浅,不懂Ruby,相关代码旨在说明概念,如有纰漏,不必挂怀;

          

     文档:

     

     系统中包含了大量的有关套接字的帮助文档:手册页,ri;

     

     手册页:

     可以使用下面命令查看用法:man 2 socket(手册页 第2节);(图)


     手册页被划分成若干节:

     ·节1:一般命令(shell程序);

     ·节2:系统调用;

     ·节3:C库函数;

     ·节4:特殊文件;

     ·节5:文件格式;

     ·节7:提供了各种话题的综述,tcp(7)就很有意思;

     

     ri:

     ri是Ruby的命令行工具,Ruby安装程序会将安装核心库文档作为整个安装过程的一部分;

     我们可以使用下面的命令查看Socket.new的文档;

     ri Socket.new;(图)


     我们就看到了之前使用的创建Socket的new方法了;

          

     本章涉及的系统调用:


     (每一章都会列出新介绍的系统调用,告诉你如何使用ri或手册页来获得更多的信息)

     ·Socket.new->socket(2)//ri Socket.new -> man 2 socket


      参考code:(未验证)

     

     创建套接字第一个套接字:          # ./code/snippets/create_socket.rb     require 'socket'     socket = Socket.new(Socket::AF_INET, Socket::Sock_STREAM)          创建套接字第二个套接字:     # ./code/snippets/create_socketmemoized.rb     require 'socket'     socket = Socket.new(:INET6, :STREAM)

总结:

Socket可以支持不同的传输层协议(TCP或UDP),当使用TCP协议进行连接时,该Socket连接就是一个TCP连接,UDP连接同理。

了解了套接字的作用和基本概念,以及套接字的创建,接下来要知道如何进行连接的建立。