LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 3317|回复: 11

给Socket套接字赋予地址过程中一些概念的澄清[转贴]

[复制链接]
发表于 2003-6-21 08:31:04 | 显示全部楼层 |阅读模式
作者:coly
原贴在这里:http://www.linuxforum.net/docnew ... mp;o=all&fpart=
  1. 首先,随着时间的推移,我会不断地向这篇里面加东西,知道我认为应该结束了为止。

  2.       这篇文档实际上是我的学习小结的一部分,所以如果有人能够来信指出其中的错误或不

  3.       足,那我可是感激淋涕了。

  4.      

  5.       我假定读者已经对于socket连接的建立过程和各种状态转换比较熟悉了,因为这篇文档的

  6.       目的是澄清概念,而不是介绍概念。



  7.       在使用socket编程时,我们都知道在网络通信以前首先要建立连接,而连接的建立是通过

  8.       对socket的一些操作来完成的。那么,建立连接的过程大致可以分为以下几步:

  9.       1. 建立socket套接字。

  10.       2. 给套接字赋予地址,这个地址不是通常的网络地址的概念。

  11.       3. 建立socket连接。





  12.       1. 建立socket套接字。

  13.       使用socket建立套接字的时候,我们实际上是建立了一个数据结构。这个数据结构最主要

  14.       的信息是指定了连接的种类和使用的协议,此外还有一些关于连接队列操作的结构字段

  15.       (这里就先不涉及他们了)。

  16.       当我们使用socket函数以后,如果成功的话会返回一个int型的描述符,它指向前面那个

  17.       被维护在内核里的socket数据结构。我们的任何操作都是通过这个描述符而作用到那个数

  18.       据结构上的。这就像是我们在建立一个文件后得到一个文件描述符一样,对文件的操作都

  19.       是通过文件描述符来进行的,而不是直接作用到inode数据结构上。我之所以用文件描述

  20.       符举例,是因为socket数据结构也是和inode数据结构密切相关,它不是独立存在于内核

  21.       中的,而是位于一个VFS inode结构中。所以,有一些比较抽象的特性,我们可以用文件

  22.       操作来不恰当的进行类比以加深理解。

  23.       如前所述,当建立了这个套接字以后,我们可以获得一个象文件描述符那样的套接字描述

  24.       符。就象我们对文件进行操作那样,我们可以通过向套接字里面写数据将数据传送到我们

  25.       指定的地方,这个地方可以是远端的主机,也可以是本地的主机。如果你有兴趣的话,还

  26.       可以用socket机制来实现IPC,不过效率比较低,试试也就行了(我没有试过)。



  27.       2. 给套接字赋予地址。

  28.       依照建立套接字的目的不同,赋予套接字地址的方式有两种:服务器端使用bind,客户端

  29.       使用connetc。

  30.       Bind:

  31.       我们都知道,只要使用IP, prot就可以区分一个tcp/ip连接(当然这个连接指的是一个

  32.       连接通道,如果要区分特定的主机间的连接,还需要第三个属性 hostname)。

  33.       我们可以使用bind函数来为一个使用在服务器端例程中的套接字赋予通信的地址和端口。

  34.       在这里我们称通信的IP地址和端口合起来构成了一个socket地址,而指定一个socket使

  35.       用特定的IP和port组合来进行通行的过程就是赋予这个socket一个地址。

  36.       要赋予socket地址,就得使用一个数据结构来指明特定的socket地址,这个数据结构就

  37.       是struct sockaddr。对它的使用我就不说了,因为这篇文档的目的是澄清概念而不是说

  38.       明使用方法。Bind函数的作用就是将这个特定的标注有socket地址信息的数据结构和

  39.       socket套接字联系起来,即赋予这个套接字一个地址。但是在具体实现上,他们两个是怎

  40.       么联系在一起的,我还不知道。

  41.       一个特定的socket的地址的生命期是bind成功以后到连接断开前。你可以建立一个

  42.       socket数据结构和socket地址的数据结构,但是在没有bind以前他们两个是没有关系

  43.       的,在bind以后他们两个才有了关系。这种关系一直维持到连接的结束,当一个连接结束

  44.       时,socket数据结构和socket地址的数据结构还都存在,但是他们两个已经没有关系

  45.       了。如果你要是用这个套接字在socket地址上重新进行连接时,需重新bind他们两个。再

  46.       注明一次,我说的这个连接是一个连接通道,而不是特定的主机之间的连接。

  47.       Bind指定的IP通常是本地IP(一般不特别指定,而使用INADDR_ANY来声明),而最主要

  48.       的作用是指定端口。在服务器端的socket进行了bind以后就是用listen来在这个socket

  49.       地址上准备进行连接。

  50.       connect:

  51.       对于客户端来说,是不会使用bind的(并不是不能用,但没什么意义),他们会通过

  52.       connet函数来建立socket和socket地址之间的关系。其中的socket地址是它想要连接的

  53.       服务器端的socket地址。在connect建立socket和socket地址两者关系的同时,它也在

  54.       尝试着建立远端的连接。



  55.       3. 建立socket连接。

  56.       对于准备建立一个连接,服务器端要两个步骤:bind, listen;客户端一个步骤:

  57.       connct。如果服务器端accept一个connect,而客户端得到了这个accept的确认,那么

  58.       一个连接就建立了。





  59.       对于更细节的东西,大家可以参看《Linux网络编程》(林宇,郭凌云著)和《GNU C库技

  60.       术手册》(机械工业出版社)。我认为后一本书更标准一些,如果手头有的话,最好看看。
复制代码
发表于 2003-6-21 21:26:21 | 显示全部楼层

in addition

不错。总结的不错。
但有些细节没讲,如tcp与udp联接是有区别的。
kj501讲的是tcp协议的方式联接,若是udp方式,则有地方需要注意。
有client方调用connect()时,tcp方式是向server发出请求;
在udp方式下则不同,connect()并不向server发出请求。
 楼主| 发表于 2003-6-21 21:34:11 | 显示全部楼层
首先声明,这张贴子不是我写的。
另外,tcp方式是有连接的,而udp方式是无连接的。这点特点决定了再者的区别。
发表于 2004-8-9 11:02:40 | 显示全部楼层
这里有个问题,在UDP客户端编程的时候,如何指定源端口(source port)呢?
它指定的sockaddr_in结构中的port好象是目的端口(dsn port)??
发表于 2004-8-9 11:18:48 | 显示全部楼层
不管udp还是tcp,源端口是不需要指定,也不需要知道的
它是系统自动分配的
发表于 2004-8-9 11:49:53 | 显示全部楼层
但是服务器返回时却指定端口,而不是客户端的源端口,我该如何接收服务器发回的包呢?直接用recvfrom好象收不到啊?
发表于 2004-8-9 12:30:47 | 显示全部楼层
int  recvfrom(int  s, void *buf, size_t len, int flags, struct sockaddr
       *from, socklen_t *fromlen);
检查你的函数用的是否有问题
这里有个容易犯的错误是没有给 *fromlen 赋值
socklen_t alen = sizeof (struct sockaddr_in);
recvfrom(..., &alen);
发表于 2004-8-9 12:43:45 | 显示全部楼层
我已经赋值了
我觉得socket一建立之后,系统自动分配了源端口,之后就在这个端口接收数据,所以就无法收到服务器指定端口发送的数据.
我另建一个socket,绑定服务器的发送端口,就可以收到了.
发表于 2004-8-9 13:08:43 | 显示全部楼层
那你这个程序情况就比较特殊了
一般UDP服务器在发送时不用显式地规定目的端口
它根据客户端发来的报文得到目的地址和端口
发表于 2004-8-9 22:01:04 | 显示全部楼层
晕,有误导嫌疑,还是去好好看看steven的书吧!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表