socket和tcp/ip

要写网络程序就必须用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接口,区分来自不同应用程序进程或网络连接的通信,实现数据传输的并发服务

<think>好的,我现在需要向用户解释socketTCP/IP通信协议。首先,我得理清这两个概念的关系各自的作用。SocketTCP/IP经常被一起提到,但用户可能不清楚它们之间的区别联系。我应该从基础开始,逐步展开。 首先,TCP/IP协议族是互联网通信的基础,包括IP、TCP、UDP等协议。用户可能知道HTTP或者网页浏览,但背后的传输层协议是TCP/IP。需要解释TCPIP各自的职责:IP负责寻址路由,而TCP确保可靠传输。这里可能需要比较TCPUDP的不同,比如TCP是面向连接的,可靠;UDP是无连接的,速度快但不保证送达。 然后是socket的概念。Socket作为应用程序传输层之间的接口,允许程序通过网络通信。用户可能听说过“套接字”这个词,但具体怎么工作的需要说明。比如,socket如何利用IP端口号来建立连接,TCP的三次握手过程,数据传输,以及四次挥手断开连接的过程。 接下来,可能需要将socketTCP/IP结合起来解释整个通信流程。例如,服务器创建socket,绑定端口,监听连接;客户端发起连接请求,建立TCP连接后,双方通过socket发送接收数据。这个过程需要详细但简洁的步骤说明,避免技术术语过多让用户困惑。 另外,要注意用户可能的疑问点。比如,socket是否只用于TCP?其实socket也支持UDP其他协议,但这里重点在TCP/IP。还有,为什么需要三次握手?可能需要简单解释以确保可靠性,防止旧的重复连接请求造成混乱。 还需要考虑实际应用中的例子,比如网页服务器使用80端口,客户端如何通过IP端口访问。或者,socket编程中的常见函数,如bind、listen、accept、connect等,但可能不需要深入代码,而是概念上的描述。 最后,总结两者的关系:TCP/IP是通信协议的标准,而socket是实现这些协议的API,使得应用程序能够利用这些协议进行通信。确保用户理解socket是工具,而TCP/IP是规则,两者共同促成网络通信。 检查是否有遗漏点,比如数据包的结构、IP地址的作用、端口号的意义,以及可能涉及的常见问题如防火墙、端口阻塞等,但可能超出当前问题的范围,暂时不深入。保持回答结构清晰,逐步引导用户理解基本概念流程。</think>### 理解SocketTCP/IP通信协议的分步解析 --- #### 一、**TCP/IP协议族:网络通信的基石** TCP/IP协议族是互联网通信的核心标准,由多个协议分层协作组成: 1. **IP协议(网络层)** - **作用**:负责将数据包从源设备路由到目标设备,通过IP地址唯一标识设备。 - **特点**:无连接、不可靠(不保证数据到达顺序或是否丢失)。 - **示例**:$$ \text{数据包格式} = \text{源IP} + \text{目标IP} + \text{数据内容} $$ 2. **TCP协议(传输层)** - **作用**:在IP基础上提供可靠、有序的字节流传输。 - **核心机制**: - **三次握手建立连接**: ```plaintext 客户端 → SYN → 服务端 客户端 ← SYN-ACK ← 服务端 客户端 → ACK → 服务端 ``` - **数据分段与确认重传**:将数据拆分为段(Segment),接收方需确认收到,否则重传。 - **四次挥手断开连接**: ```plaintext A → FIN → B A ← ACK ← B A ← FIN ← B A → ACK → B ``` 3. **TCP vs UDP** - **TCP**:可靠传输,适合文件传输、网页浏览。 - **UDP**:低延迟但不可靠,适合视频流、实时游戏。 --- #### 二、**Socket:应用层与传输层的桥梁** Socket是操作系统提供的编程接口,允许应用程序通过TCP/IP协议进行通信。 1. **Socket的核心要素** - **IP地址**:标识网络中的设备(如`192.168.1.1`)。 - **端口号**:标识设备上的具体应用(如HTTP默认端口`80`)。 - **协议类型**:TCP或UDP。 2. **Socket通信流程(以TCP为例)** - **服务端**: ```plaintext 1. 创建Socketsocket() 2. 绑定IP端口 → bind() 3. 监听连接 → listen() 4. 接受请求 → accept() 5. 读写数据 → recv()/send() 6. 关闭连接 → close() ``` - **客户端**: ```plaintext 1. 创建Socketsocket() 2. 发起连接 → connect() 3. 读写数据 → recv()/send() 4. 关闭连接 → close() ``` 3. **SocketTCP/IP的关系** - **TCP/IP**:定义通信规则(如何寻址、如何传输)。 - **Socket**:提供实现这些规则的编程接口(即API)。 --- #### 三、**实际案例:网页访问过程** 1. 用户在浏览器输入`http://example.com`。 2. 浏览器通过DNS解析获取目标服务器的IP地址(如`93.184.216.34`)。 3. 浏览器创建Socket,通过TCP协议向服务器`80`端口发起连接。 4. 服务器接受连接后,浏览器发送HTTP请求(如`GET /index.html`)。 5. 服务器返回网页数据,浏览器渲染显示。 --- #### 四、**常见问题** - **为什么需要端口号?** 一台设备可能运行多个服务(如同时开启网页邮件服务),端口号用于区分不同服务。 - **Socket是否只能用于TCP?** 否,Socket也支持UDP协议,但TCP更常用。 - **三次握手的必要性?** 确保双方均具备收发能力,防止历史重复连接干扰。 --- #### 总结 - **TCP/IP**是通信协议标准,确保数据可靠传输。 - **Socket**是编程接口,简化应用程序调用协议的过程。 - 两者结合,构成了互联网应用(如网页、即时通讯)的基础。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值