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

网络编程笔记一、Socket套接字

2017-12-06 10:37 363 查看

网络编程笔记一、Socket套接字

@(网络编程笔记)[socket起源|基础内容]

引言: 这篇笔记将简单介绍socket的起源、基础知识。

网络编程笔记一、Socket套接字
一、 Socket概述
1.1、socket起源

1.2、Socket的功能

1.3、Socket套接字的三种类型

二、 Socket基础知识
2.1、Socket套接字是什么?

2.2、Socket套接字是怎样在网络上传输数据的?

一、 Socket概述

  由于每个主机系统都有各自命名进程的方法,而且常常是不兼容的,因此,要在全网范围内硬把进程名字统一起来是不现实的。所以,每个计算机网络中都要引入一种起媒介作用的、全网一致的标准名字空间。这种标准名字,在ARPA网中称作socket套接字。

  在操作系统中,通常会为应用程序提供一组应用程序接口(API),称为套接字接口(英语:socket API)。应用程序可以通过套接字接口,来使用网络套接字,以进行数据交换。在套接字接口中,以IP地址及通信端口组成套接字地址(socket address)。远程的套接字地址,以及本地的套接字地址完成连接后,再加上使用的协议(protocol),这个五元组(five-element tuple),作为套接字对(socket pairs),之后就可以彼此交换数据。 —— 维基百科

  网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。建立网络通信连接至少要一对端口号(socket)。socket本质是编程接口(API),对TCP/IP的封装,TCP/IP也要提供可供程序员做网络开发所用的接口,这就是Socket编程接口。 —— 百度百科

1.1、socket起源

  在 80 年代早期,远景研究规划局(Advanced Research Projects Agency, ARPA)资助了佳利福尼亚大学伯克利分校的一个
4000
研究组,让他们将 TCP/IP 软件移植到 UNIX 操作系统中,并将结果提供给其他网点。作为项目的一部分,设计者们创建了一个接口,应用进程使用这个接口可以方便的进行通信。

  他们决定,只要有可能,就使用以有的系统调用,对那些不能方便的容入已有的函数集的情况,就再增加新的系统调用以支持 TCP/IP 功能。这样做的结果就出现了插口接口(Berkeley Socket) ,这个系统被称为 Berkeley UNIX或 BSD UNIX 。后期许多计算机厂商,都采用了 Berkeley UNIX,于是许多机器上都可以使用 Socket 了。这样,Socket 接口就被广泛使用,到现在已经成为事实上的标准。

  这个例子是模拟伯克利接口,我们通过80端口发送
hello,world
到1.2.3.4的主机上。演示一下创建接口,连接远程主机,发送数据,关闭接口的过程.

Socket socket = getSocket(type = "TCP")
connect(socket, address = "1.2.3.4", port = "80")
send(socket, "Hello, world!")
close(socket)


1.2、Socket的功能

  Socket 实质上提供了进程通信的端点。

   Socket 是面向客户-服务器模型而设计的,针对客户和服务器程序提供不同的 Socket 系统调用。客户随机申请一个 Socket 号 ;服务器拥有全局公认的 Socket,任何客户都可以向它发出连接请求和信息请求。Socket 利用客户— 服务器模式巧妙的解决了进程之间建立通信连接的问题。服务器Socket 为全局所公认非常重要。

   两个完全随机的用户进程之间,因为没有任何一方的 Socket是固定的,就像打电话却不知道别人的电话号码,要通话是不可能的。



  Socket 的英文原意就是“孔”或“插座” ,现在,作为 BSD UNIX 的进程通讯机制,取其后一种意义。日常生活中常见的插座,有的是信号插座,有的是电源插座,Socket 非常相似于电话插座。

  将电话系统与面向连接的 Socket 机制相比,有着惊人的相似。以一个国家级的电话网为例。电话的通话双方相当于相互通信的两个进程;通话双方所在的地区(享有一个全局唯一的区号)相当于一个网络,区号是它的网络地址;区内的一个单位的交换机相当于一台主机,主机分配给每个用户的局内号码相当于 Socket 号。

  过程:任何用户在通话之前,首先要占有一部电话机,相当于申请一个 Socket 号;同时要知道对方的电话号码,相当于对方有一个 Socket。然后向对方拨号呼叫,相当于发出连接请求(假如对方不在同一区内,还要拨对方区号,相当于给出网络地址) 。对方假如在场并空闲(相当于通信的另一主机开机且可以接受连接请求) ,拿起电话话筒,双方就可以正式通话,相当于连接成功。双方通话的过程,是向电话机发出信号和从电话机接受信号的过程,相当于向 Socket 发送数据和从 Socket 接受数据。通话结束后,一方挂起电话机,相当于关闭 Socket,撤消连接。

  在电话系统中,一般用户只能感受到本地电话机和对方电话号码的存在,建立通话的过程、话音传输的过程以及整个电话系统的技术细节对它都是透明的,这也与 Socket 机制非常相似。Socket 利用网间网通信设施实现进程通信,但它对通信设施的细节毫不关心,只要通信设施能提供足够的通信能力,它就满足了

每一个 Socket 都用一个半相关描述:

{协议,本地地址,本地端口}

一个完整的 Socket 则用一个相关描述

{协议,本地地址,本地端口,远程地址,远程端口}

每一个 Socket 有一个本地的唯一 Socket 号,由操作系统分配。

1.3、Socket套接字的三种类型

1.3.1、流式套接字(SOCK_STREAM)

  流式的套接字可以提供可靠的、面向连接的通讯流。如果通过流式套接字发送了顺序的数据: “12” 。那么数据到达远程时候的顺序也是“12”。流式套接字使用了 TCP ( TheTransmission Control Protocol )协议,保证应用层次上的数据传输质量。



  注意是listen建立连接队列,监听,connect处理,箭头应指向listen。面向连接的服务器处理请求较为复杂,后面将详细介绍其三次握手及四次挥手的过程。

1.3.2、数据报套接字(SOCK_DGRAM)

  数据报套接字定义了一种无连接的服务,数据通过相互独立的报文进行传输,是无序的,并且不保证可靠,无差错。数据报套接字也使用 IP,但是它不使用 TCP,它使用使用者数据报协议 UDP。为什么说它们是“无连接”的呢?因为它(UDP)不像流式套接字那样维护一个打开的连接,你只需要把数据打成一个包,把远程的 IP 贴上去,然后把这个包发送出去。这个过程是不需要建立连接的。

  无连接服务器一般都是面向事务处理的,一个请求一个应答就完成了客户程序与服务程序之间的相互作用。若使用无连接的套接字编程,程序的流程如下:



无连接的套接字工作过程如下:

  服务器首先启动,通过调用 socket() 建立一个套接字,然后调用bind()将该套接字和本地网络地址联系在一起,再调用 listen() 使套接字做好侦听的准备,并规定它的请求队列的长度, 之后就调用 accept() 来接收连接。客户在建立套接字后就可调用 connect() 和服务器建立连接。连接一旦建立,客户机和服务器之间就可以通过调用 read()和 write()来发送和接收数据。最后,待数据传送结束后,双方调用 close() 关闭套接字。

数据包既然会丢失,怎样能保证程序能够正常工作呢?

  事实上,每个使用 UDP的程序都要有自己的对数据进行确认的协议。比如,TFTP 协议定义了对于每一个发送出去的数据包,远程在接受到之后都要回送一个数据包告诉本地程序: “我已经拿到了!” (一个 “ACK” 包) 。如果数据包发的送者在 5 秒内没有的得到回应,它就会重新发送这个数据包直到数据包接受者回送了 “ACK ” 信号。

1.3.3、原始套接字

  原始套接字主要用于一些协议的开发,可以进行比较底层的操作。它功能强大,但是没有上面介绍的两种套接字使用方便,一般的程序也涉及不到原始套接字。

二、 Socket基础知识

2.1、Socket套接字是什么?

  在 UNIX 系统中,任何对 I/O 的操作,都是通过读或写一个文件描述符来实现的。一个文件描述符,代表一个被打开的文件(这里的文件是广义的文件,并不只代表不同的磁盘文件,它可以代表一个网络上的连接,一个先进先出队列,一个终端显示屏幕,以及其他的一切) 。如果通过 Internet 和另外一个程序通讯,将会是通过一个文件来描述符实现的。Socket套接字是通过标准的 UNIX 文件描述符和其他的程序通讯的一个方法。

  Socket 是一个文件描述符了,那么我们怎样得到这个代表网络连接的文件描述符呢?首先调用系统函数 socket(),它返回一个套接字(Socket)描述符,然后你就可以通过对这个套接字描述符进行一些操作:系统函数 send() 和 recv() 。

2.2、Socket套接字是怎样在网络上传输数据的?

1、在发送端,数据被分成一个一个的包 (Packet) , 包的数据头 (或数据尾)被第一层协议 (比如 TFTP协议) 加上第一层协议数据;然后整个包(包括内部加入的 TFTP 信息头)被下层协议再次包装(比如 UDP) ,再这之后数据包会再次被下层协议包装(比如 IP 协议) ,最后是被最底层的硬件层(物理层)包装上最后一层信息(Ethernet 信息头)。

2、在接收端,当计算机接收到这个包后,硬件首先剥去数据包中的 Ethernet 信息头,然后内核在剥去 IP 和 UDP 信息头,最后把数据包提交给 TFTP 应用程序,由 TFTP 剥去 TFTP信息头,最后得到了原始数据。

通过这个网络模型,你可以写套接字的应用程序而不必在乎事实上数据在物理层中的传输方法

在 Linux 中,真正用到的网络模型是下面这样划分的:

- 应用层 :(Telnet,Ftp,等等)

- 主机间运输层(TCP 和 UDP)

- 网络层(IP 和路由)

- 网络底层(相当于 OSI 模型中数据链路和物理层)

参考资料:

《linux网络编程》
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: