您的位置:首页 > 理论基础 > 计算机网络

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

2017-07-18 16:18 337 查看

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连接同理。

了解了套接字的作用和基本概念,以及套接字的创建,接下来要知道如何进行连接的建立。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  socket