【转】TCP和SOCKET关系
socket是TCP/IP协议的API
TCP是数据的介质,Socket是TCP的介质.socket通信在哪一层
查了⼀下RFC⽂档,Socket是RFC147,更新时间是1971年.TCP是RFC793,更新时间是1981年.Socket在ARPA⽹就出现了.
应该说TCP是socket上的⼀种通信协议.
要写⽹络程序就必须⽤Socket,这是程序员都知道的。⽽且,⾯试的时候,我们也会问对⽅会不会Socket编程?⼀般来说,很多⼈都会
说,Socket编程基本就是listen,accept以及send,write等⼏个基本的操作。是的,就跟常见的⽂件操作⼀样,只要写过就⼀定知道。
对于⽹络编程,我们也⾔必称TCP/IP,似乎其它⽹络协议已经不存在了。对于TCP/IP,我们还知道TCP和UDP,前者可以保证数据的正确和可靠性,后者则允许数据丢失。最后,我们还知道,在建⽴连接前,必须知道对⽅的IP地址和端⼝号。除此,普通的程序员就不会知道太多了,很多时候这些知识已经够⽤了。最多,写服务程序的时候,会使⽤多线程来处理并发访问。
我们还知道如下⼏个事实:
1。⼀个指定的端⼝号不能被多个程序共⽤。⽐如,如果IIS占⽤了80端⼝,那么Apache就不能也⽤80端⼝了。
2。很多防⽕墙只允许特定⽬标端⼝的数据包通过。
3。服务程序在listen某个端⼝并accept某个连接请求后,会⽣成⼀个新的socket来对该请求进⾏处理。
于是,⼀个困惑了我很久的问题就产⽣了。如果⼀个socket创建后并与80端⼝绑定后,是否就意味着该socket占⽤了80端⼝呢?如果是这样的,那么当其accept⼀个请求后,⽣成的新的socket到底使⽤的是什么端⼝呢(我⼀直以为系统会默认给其分配⼀个空闲的端⼝号)?如果是⼀个空闲的端⼝,那⼀定不是80端⼝了,于是以后的TCP数据包的⽬标端⼝就不是80了--防⽕墙⼀定会组织其通过的!实际上,我们可以看到,防⽕墙并没有阻⽌这样的连接,⽽且这是最常见的连接请求和处理⽅式。我的不解就是,为什么防⽕墙没有阻⽌这样的连接?它是如何判定那条连接是因为connet80端⼝⽽⽣成的?是不是TCP数据包⾥有什么特别的标志?或者防⽕墙记住了什么东西?
后来,我⼜仔细研读了TCP/IP的协议栈的原理,对很多概念有了更深刻的认识。⽐如,在TCP和UDP同属于传输层,共同架设在IP层(⽹络层)之上。⽽IP层主要负责的是在节点之间(End to End)的数据
包传送,这⾥的节点是⼀台⽹络设备,⽐如计算机。因为IP层只负责把数据送到节点,⽽不能区分上⾯的不同应⽤,所以TCP和UDP协议在其基础上加⼊了端⼝的信息,端⼝于是标识的是⼀个节点上的⼀个应⽤。除了增加端⼝信息,UPD协议基本就没有对IP层的数据进⾏任何的处理了。⽽TCP协议还加⼊了更加复杂的传输控制,⽐如滑动的数据发送窗⼝(Slice Window),以及接收确认和重发机制,以达到数据的可靠传送。不管应⽤层看到的是怎样⼀个稳定的TCP数据流,下⾯传送的都是⼀个个的IP数据包,需要由TCP协议来进⾏数据重组。
所以,我有理由怀疑,防⽕墙并没有⾜够的信息判断TCP数据包的更多信息,除了IP地址和端⼝号。⽽且,我们也看到,所谓的端⼝,是为了区分不同的应⽤的,以在不同的IP包来到的时候能够正确转发。
TCP/IP只是⼀个协议栈,就像操作系统的运⾏机制⼀样,必须要具体实现,同时还要提供对外的操作接⼝。就像操作系统会提供标准的编程接⼝,⽐如Win32编程接⼝⼀样,TCP/IP也必须对外提供编程接⼝,这就是Socket编程接⼝--原来是这么回事啊!
在Socket编程接⼝⾥,设计者提出了⼀个很重要的概念,那就是socket。这个socket跟⽂件句柄很相似,实际上在BSD系统⾥就是跟⽂件句柄⼀样存放在⼀样的进程句柄表⾥。这个socket其实是⼀个序号,表⽰其在句柄表中的位置。这⼀点,我们已经见过很多了,⽐如⽂件句柄,窗⼝句柄等等。这些句柄,其实是代表了系统中的某些特定的对象,⽤于在各种函数中作为参数传⼊,以对特定的对象进⾏操作--这其实是C语⾔的问题,在C++语⾔⾥,这个句柄其实就是this指针,实际就是对象指针啦。
现在我们知道,socket跟TCP/IP并没有必然的联系。Socket编程接⼝在设计的时候,就希望也能适应其他的⽹络协议。所以,socket的出现只是可以更⽅便的使⽤TCP/IP协议栈⽽已,其对TCP/IP进⾏了抽象,形成了⼏个最基本的函数接⼝。⽐如
create,listen,accept,connect,read和write等等。
现在我们明⽩,如果⼀个程序创建了⼀个socket,并让其监听80端⼝,其实是向TCP/IP协议栈声明了其对80端⼝的占有。以后,所有⽬标
是80端⼝的TCP数据包都会转发给该程序(这⾥的程序,因为使⽤的是Socket编程接⼝,所以⾸先由Socket层来处理)。所谓accept函数,其实抽象的是TCP的连接建⽴过程。accept函数返回的新socket其实指代的是本次创建的连接,⽽⼀个连接是包括两部分信息的,⼀个是源IP和源端⼝,另⼀个是宿IP和宿端⼝。所以,accept可以产⽣多个不同的socket,⽽这些socket⾥包含的宿IP和宿端⼝是不变的,变化的只是源IP和源端⼝。这样的话,这些socket宿端⼝就可以都是80,⽽Socket层还是能根据源/宿对来准确地分辨出IP包和socket的归属关系,从⽽完成对TCP/IP协议的操作封装!⽽同时,放⽕墙的对IP包的处理规则也是清晰明了,不存在前⾯设想的种种复杂的情形。
明⽩socket只是对TCP/IP协议栈操作的抽象,⽽不是简单的映射关系,这很重要!
1、TCP连接
⼿机能够使⽤联⽹功能是因为⼿机底层实现了TCP/IP协议,可以使⼿机终端通过⽆线⽹络建⽴TCP连接。TCP协议可以对上层⽹络提供接⼝,使上层⽹络数据的传输建⽴在“⽆差别”的⽹络之上。
建⽴起⼀个TCP连接需要经过“三次握⼿”:
第⼀次握⼿:客户端发送syn包(syn=j)到服务器,并进⼊SYN_SEND状态,等待服务器确认;
第⼆次握⼿:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时⾃⼰也发送⼀个SYN包(syn=k),即SYN+ACK包,此时服务器进⼊SYN_RECV状态;
第三次握⼿:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进⼊ESTABLISHED状态,完成三次握⼿。
握⼿过程中传送的包⾥不包含数据,三次握⼿完毕后,客户端与服务器才正式开始传送数据。理想状态下,TCP连接⼀旦建⽴,在通信双⽅中的任何⼀⽅主动关闭连接之前,TCP 连接都将被⼀直保持下去。断开连接时服务器和客户端均可以主动发起断开TCP连接的请求,断开过程需要经过“四次握⼿”(过程就不细写了,就是服务器和客户端交互,最终确定断开)
2、HTTP连接
HTTP协议即超⽂本传送协议(Hypertext Transfer Protocol ),是Web联⽹的基础,也是⼿机联⽹常⽤的协议之⼀,HTTP协议是建⽴在TCP 协议之上的⼀种应⽤。
HTTP连接最显著的特点是客户端发送的每次请求都需要服务器回送响应,在请求结束后,会主动释放连接。从建⽴连接到关闭连接的过程称为“⼀次连接”。
1)在HTTP 1.0中,客户端的每次请求都要求建⽴⼀次单独的连接,在处理完本次请求后,就⾃动释放连接。
2)在HTTP 1.1中则可以在⼀次连接中处理多个请求,并且多个请求可以重叠进⾏,不需要等待⼀个请求结束后再发送下⼀个请求。
由于HTTP在每次请求结束后都会主动释放连接,因此HTTP连接是⼀种“短连接”,要保持客户端程序的在线状态,需要不断地向服务器发起连接请求。通常的做法是即时不需要获得任何数据,客户端也保持每隔⼀段固定的时间向服务器发送⼀次“保持连接”的请求,服务器在收到该请求后对客户端进⾏回复,表明知道客户端“在线”。若服务器长时间⽆法收到客户端的请求,则认为客户端“下线”,若客户端长时间⽆法收到服务器的回复,则认为⽹络已经断开。
3、SOCKET原理
3.1套接字(socket)概念
套接字(socket)是通信的基⽯,是⽀持TCP/IP协议的⽹络通信的基本操作单元。它是⽹络通信过程中端点的抽象表⽰,包含进⾏⽹络通信必须的五种信息:连接使⽤的协议,本地主机的IP地址,本地进程的协议端⼝,远地主机的IP地址,远地进程的协议端⼝。
应⽤层通过传输层进⾏数据通信时,TCP会遇到同时为多个应⽤程序进程提供并发服务的问题。多个TCP连接或多个应⽤程序进程可能需要通过同⼀个 TCP协议端⼝传输数据。为了区别不同的应⽤程序进程和连接,许多计算机操作系统为应⽤程序与TCP/IP协议交互提供了套接字(Socket)接⼝。应⽤层可以和传输层通过Socket接⼝,区分来⾃不同应⽤程序进程或⽹络连接的通信,实现数据传输的并发服务

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。