socket与tcp的情感纠葛

来源:互联网 发布:网络理财诈骗案 编辑:程序博客网 时间:2024/05/01 15:16

  今天看计算机网络自顶向下方法时,一句话没有想明白,tcp套接字是由一个四元组(源ip,源端口,目的ip,目的端口)确定,疑问来了,tcp套接字一旦established,不是会分配或指定一个唯一端口吗?难道两个tcp套接字目的ip,目地端口相同,只是源ip或者源端口不同吗?这样tcp套接字就不用2元组了,只需要后两者,因为端口是唯一的。在深入想一下,服务器,socket建立,bind(),listen(),然后accept(),这里accept()函数返回的套接字就是建立连接的套接字,他们的源端口是多少呢?是指定的端口号呢,还是随机分配的?同上,可能很多人还会想着,这些端口是不同的,会随机分配,其实结果是错误的,端口号都是绑定的。也就是所有这些accept函数返回的套接字,和服务器套接字都共用了这一个端口号。很容易验证,写一个c/s,看一下几个客户端时候服务器应答端口就能明白。这也就说明了,端口是分配给进程的,几个socket如果在一个进程中,就可以分配同一个端口。这也就解释了,防火墙对指定端口进行限制,但并不限制了你程序中其他套接字。也就说明了,我们不用担心端口不够用!

  通俗的一点说,在多线程情况下,服务器端监听(listen)某个端口(假设8080)后,每accept一个客户端的连接就会产生一个新的Socket。那么这些新产生的Socket的端口是什么?程序里肯定没有指定,那就应该有两种可能,1:产生随机端口。2:还是8080端口。第一种假设想了就觉得不可能,防火墙非常有可能会阻止这些随机端口的包。那么就是第二种假设了,服务端端口还是8080。所以,为了能够使“客户端发给服务端的同一端口(8080)不同线程(即不同的Socket连接)的包能够被区分开并进行组合”,必须得有一个区分包是来自不同连接的显著特征,那就是传输层包头里的源端口了,即一个Socket连接里客户端那方的端口。总结一下,对于这种情况,就是传输层包头里源端口(客户端)会随着产生的Socket不同,而宿端口相同(服务器端)。如果一个程序创建了一个socket,并让其监听80端口,其实是向TCP/IP协议栈声明了其对80端口的占有。以后,所有目标是80端口的TCP数据包都会转发给该程序(这里的程序,因为使用的是Socket编程接口,所以首先由Socekt层来处理)。所谓的accept函数,其实抽象的是TCP的连接建立过程。accept函数返回的新socket其实指代的是本次创建的连接,而一个连接是包括两部分信息的,一个是源IP和源端口,另一个宿IP和宿端口这样的话,这些socket宿端口就可以都是80!

  对于connect()函数,其实就是tcp客户机向服务器建立3次握手,而tcp3次握手后建立的连接正是accept()创建的socket!

 

 

原创粉丝点击