C 语言是我接触的第一门编程语言,一直以来有个问题困扰着我,它有什么用?!尽管 UNIX 系统也是 C 写出来的,但是在接触它时,书上只是生硬地教你怎么用函数打印出简单图案,教你去应试,直到此刻,我才发现它的强大和实用。


Socket的英文原义是 "孔" 或 "插座",在计算机中称作 "套接字",用于描述 IP 地址和端口,是一个通信链的句柄。多个 TCP 连接或多个应用程序进程可能需要通过同一个 TCP 协议端口传输数据。为了区别不同的应用程序进程和连接,许多计算机操作系统为应用程序与 TCP/IP 协议交互提供了称为套接字(Socket)的接口。

非常非常简单的举例说明下:Socket=Ip address+ TCP/UDP port。


分类

①. 流套接字(SOCK_STREAM):

流套接字用于提供面向连接、可靠的数据传输服务。该服务将保证数据能够实现无差错、无重复发送,并按顺序接收。流套接字之所以能够实现可靠的数据服务,原因在于其使用了传输控制协议,即TCP(The Transmission Control Protocol)协议。


服务器端程序:

(1)创建套接字(socket)

(2)将套接字绑定到一个本地地址和端口上(bind)

(3)将套接字设为监听模式,准备接收客户端请求(listen)

(4)等待客户端请求的到来,当请求到来后,接受连接请求,返回一个新的对应于此次连接的套接字(accept)

(5)用返回的套接字和客户端进行通信(send/recv)

(6)返回,等待另一个客户端请求

(7)关闭套接字


客户端程序:

(1)创建套接字(socket)

(2)向服务器发出连接请求(connect)

(3)和服务器进行通信(send/recv)

(4)关闭套接字

客户端不用绑定端口,因为当服务器接收到请求时已经记录下客户端的端口号。


②. 数据包套接字(SOCK_DGRAM):

数据包套接字提供了一种无连接的服务。该服务并不能保证数据传输的可靠性,数据有可能在传输过程中丢失或出现数据重复,且无法保证顺序地接收到数据。数据包套接字使用UDP(User Datagram Protocol)协议进行数据的传输。由于数据包套接字不能保证数据传输的可靠性,对于有可能出现的数据丢失情况,需要在程序中做相应的处理。

(UDP socket 和 TCP socket 最大的区别在于,服务器无须 listen,客户端无须 connect,因此 UDP 中的服务器和客户端的区别相对较模糊)


③. 原始套接字(SOCK_RAW):

原始套接字与标准套接字(标准套接字指的是前面介绍的流套接字和数据包套接字)的区别在于:原始套接字可以读写内核没有处理的IP数据包,而流套接字只能读取TCP协议的数据,数据包套接字只能读取UDP协议的数据。因此,如果要访问其他协议发送数据必须使用原始套接字。


套接字通信

①. 要通过 Internet 进行通信,至少需要一对套接字,其中一个运行在客户端,称之为 ClientSocket,另一个运行于服务器端面,称为 ServerSocket。根据连接启动的方式以及本地要连接的目标,套接字之间的连接过程可以分为三个步骤:服务器监听、客户端请求、连接确认。

服务器监听:服务端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态。

客户端请求:由客户端的套接字提出连接请求,要连接的目标是服务器端套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器套接字的地址和端口号,然后再向服务器端套接字提出连接请求。

连接确认:当服务器端套接字监听到或者说接收到客户端套接字的连接请求时,它就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的信息发送给客户端,一旦客户端确认了此连接,连接即可建立。而服务器端继续处于监听状态,继续接收其他客户端的连接请求。

②. 使用套接字进行数据处理有两种基本模式:同步和异步。

同步模式:

同步模式的特点是在通过 Socket 进行连接、接收、发送数据时,客户机和服务器在接收到对方响应前会处于阻塞状态,即一直等到收到对方请求进才继续执行下面的语句。可见,同步模式只适用于数据处理不太多的场合。当程序执行的任务很多时,长时间的等待可能会让用户无法忍受。

异步模式:

异步模式的特点是在通过 Socket 进行连接、接收、发送操作时,客户机或服务器不会处于阻塞方式,而是利用 callback 机制进行连接、接收、发送处理,这样就可以在调用发送或接收的方法后直接返回,并继续执行下面的程序。可见,异步套接字特别适用于进行大量数据处理的场合。

使用同步套接字进行编程比较简单,而异步套接字编程则比较复杂。