Chinaunix

标题: *******网络编程基础( 讨论版V1 )******* [打印本页]

作者: 蓝色键盘    时间: 2003-04-02 13:50
标题: *******网络编程基础( 讨论版V1 )*******
最近这里有关网络编程方面的讨论比较多,我就抛砖引玉,就有关网络编程问题(主要讨论应用层到传输层的接口),给几个讨论的话题,从最基本的开始,每次讨论5个话题,希望各位论坛朋友参与讨论,畅所欲言!

1、套接口是什么?套接口和套节字是什么关系?

2、TCP和UDP有什么区别?

3、IPV4和IPV6由什么区别?如何互操作?

4、TCP的三路握手和四分组连接终止序列的过程分别是什么?

5、在TCP状态转化的过程中,分析如下几种状态:
TIME_WAIT、FIN_WAIT_1、FIN_WAIT_2、CLOSE_WAIT和LAST_WAIT。
作者: 蓝色键盘    时间: 2003-04-02 13:56
标题: *******网络编程基础( 讨论版V1 )*******
补充一点:
各位大虾,讨论的时候请针对上面的问题,使用数字1、2、3、4、5分别对应上述问题分别描述。
作者: 无双    时间: 2003-04-02 18:23
标题: *******网络编程基础( 讨论版V1 )*******
好累啊
要真仔细说的话还是真的累
因为知识点很多了

2TCP是有连接的,UDP是无连接的。有连接的话保证数据流准确按序收发,并且在收发错误时会报错

UDP不保证发送的按序,并且不保证能够发送,当然如果网络没有问题的话
那么使用它还是会发送成功的
3 IPV4 和V6区别在于IP地址长度不一样
另外如果在IP层比较的话
那么它们的包长不一样
还有
IPV6分包只能在发送方进行
作者: 蓝色键盘    时间: 2003-04-02 18:47
标题: *******网络编程基础( 讨论版V1 )*******
非常好,斑竹首先说话了!
对于上述讨论点,可以针对某个说说自己的意见。
作者: gadfly    时间: 2003-04-02 19:04
标题: *******网络编程基础( 讨论版V1 )*******
http://edu.sdinfo.net/74596379271364608/20021106/1097592.shtml

1.
套接字是网络通信的基本构件,它提供了不同主机间进程双向通信的端点.
套接字存在于特定的通信域(即地址族)中,只有隶属于同一地址族的套接字才能建立对话。Linux支持AF_INET(IPv4协议)、AF_INET6(IPv6协议)和AF_LOCAL(Unix域协议)。

Linux支持以下的socket families或domain:

◆ Unix domain sockets;

◆ INET TneIntemet address family supports communications via;

◆ TCP/IP protocols;

◆ Amateur radio X.25;

◆ Novel IPX;

◆ Appletalk DDP;

◆ X.25。

套接口(socket)=网络地址+端口号。,要建立一个套接口必须调用socket函数,套接口有三种类型,即字节流套接口(SOCK_STREAM),数据报套接口(SOCK_DGRAM)和原始套接口(SOCK_RAW)。

4,5说起来太累,得把那tcp/ip详解上的图贴上来,才直观
作者: 蓝色键盘    时间: 2003-04-02 19:40
标题: *******网络编程基础( 讨论版V1 )*******
对gadfly 的一点补充:

定义一个连接的一个端点的两元组,即IP地址和端口号,称为一个套接口。在网络连接中,两个端点所组成的四元组(即本地IP、本地PORT、远程IP和远程PORT)称为socket pair,该四元组唯一的标识了一个网络连接。该情况可通过netstat验证。该四元组一旦建立便可读写数据到该接口。

套节字是用来引用和访问套接口的描述字(应用程序便是通过该描述字调用API与内核交互的),并且一个套接字唯一的对应一个套接口,反之,一个套接口可以有多个套节字。
作者: gadfly    时间: 2003-04-02 20:49
标题: *******网络编程基础( 讨论版V1 )*******
5.
连接过程是通过一系列状态表示的,这些状态有:LISTEN,SYN-SENT,SYN-RECEIVED,ESTABLISHED,FIN-WAIT-1,FIN-WAIT-2,CLOSE-WAIT,CLOSING,LAST-ACK,TIME-WAIT和 CLOSED。CLOSED表示没有连接,各个状态的意义如下:

LISTEN - 侦听来自远方TCP端口的连接请求;

SYN-SENT - 在发送连接请求后等待匹配的连接请求;

SYN-RECEIVED - 在收到和发送一个连接请求后等待对连接请求的确认;

ESTABLISHED - 代表一个打开的连接,数据可以传送给用户;

FIN-WAIT-1 - 等待远程TCP的连接中断请求,或先前的连接中断请求的确认;

FIN-WAIT-2 - 从远程TCP等待连接中断请求;

CLOSE-WAIT - 等待从本地用户发来的连接中断请求;

CLOSING - 等待远程TCP对连接中断的确认;

LAST-ACK - 等待原来发向远程TCP的连接中断请求的确认;

TIME-WAIT - 等待足够的时间以确保远程TCP接收到连接中断请求的确认;

CLOSED - 没有任何连接状态;

TCP连接过程是状态的转换,促使发生状态转换的是用户调用:OPEN,SEND,RECEIVE,CLOSE,ABORT和STATUS;传送过来的数据段,特别那些包括以下标记的数据段SYN,ACK,RST和FIN;还有超时,上面所说的都会时TCP状态发生变化。

 

下面的图表示了TCP状态的转换,但这图中没有包括错误的情况和错误处理,不要把这幅图看成是总说明了。



http://www.longen.org/S-Z/details~z/TCP.htm
作者: gadfly    时间: 2003-04-02 20:54
标题: *******网络编程基础( 讨论版V1 )*******
握手和终止过程,也可以从上图中总结出来,各位可以归纳出c/s分别的状态变化序列
作者: 蓝色键盘    时间: 2003-04-02 21:52
标题: *******网络编程基础( 讨论版V1 )*******
对无双的一点补充:

针对标题2

UPD是不可靠的,如果向一个UDP套接口发送数据,那么并不能保证数据能够正确的到达,如果client发送的数据被路由丢弃或者服务器的应答信息丢失,那么client将一直阻塞,直到应用设置的超时到达,UDP需要应用来做接受确认、传输超时或者重传的机制。UDP缺乏流量控制。UDP是一个无连接协议,确省情况下client没有connect的动作(可以对UDP套接口的client或server调用connect),套接口的两个端点是通过API来标识的。一般的,UDP服务属于迭代的,而TCP服务大多数是并发的。UDP的队列机制被封装在API中。当一个TCP连接一旦成功建立,套接口的四元组是固定的,但是UDP不能保证这一点。再不能保证是否连接已建立的情况下,UDP的异步错误是不可预知的。对于一个UDP套接口可以多次调用connect,但是对于TCP只能调用一次。

TCP是面向连接的、全双工的、可靠的,TCP传输的是无记录边界有序字节流(有序是指:对于传输过程中的每个字节TCP与一个序列号关联起来),TCP通过通告窗口来控制流量。

有关TCP再此不做详细讨论,是以后讨论的重点。
作者: 蓝色键盘    时间: 2003-04-02 22:10
标题: *******网络编程基础( 讨论版V1 )*******
感谢gadfly对状态转化图的引入,不知道gadfly能否就TIME_WAIT和CLOE_WAIT和FIN_WAIT_1这三种状态做些描述,建议主要针对以下两方面来做描述:
(1)、该状态在什么情况下出现。
(2)、TCP为什么要引入该状态,分别对应与那些处理细节

一点补充,对于网络编程者而言,如果能够对TCP状态做深入的理解,那么网络应用中出现的大多数问题可通过状态图分析,从而找到原因(一些实现细节也隐含在状态图中),同时对于理解整个传输层协议由很大的帮助。
作者: 蓝色键盘    时间: 2003-04-02 22:39
标题: *******网络编程基础( 讨论版V1 )*******
3、IPv4和IPv6都属于网际协议(所有的网际协议由多个RFC定义),其版本有0、1、2、3和5,但是比较通用的是版本4和6。
版本4是80年代以后使用的比较广泛的主力协议,版本4使用32位的地址结构,主要给TCP、UDP、ICMP和IGMP提供传输分组的服务。
版本6是90年代中期设计出来的,主要变化是使用了128位的大地址结构,版本6主要给TCP、UDP和ICMPv6提供传输分组的服务。
在目前的应用中,有同时支持IPv4和IPv6的,一般称其为“IPv4/IPv6主机”或者"双栈主机"。
对于这两种协议之间的差别,可以到相关的系统中去察看,一般的在/usr/include/netinet/in.h中,各个系统定义的不尽相同,比如对于结构sockaddr_in中成员sin_len,sin_family和sin_port的数据类型的定义在很多unix系统中的定义有一定的差别,不过对于使用者来说,你只要关心它的大小就可以了,至于到底定义为哪一种类型,同样的可以到系统头文件中可以找得到。在Posix.1g中定义的套接口地址结构如下:
IPv4的定义:
struct in_addr {
in_addr_t s_addr;
};
struct sockaddr_in{
unit8_t sin_len;
sa_family_t sin_family;
in_port_t sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
其中成员sin_zero暂时没有使用到,用来扩充功能,一般在使用时将其初始化为0,事实上,Posix.1g只需要这个结构中的三个成员sin_family、sin_port和sin_addr,加入其他的两项完全是为了兼容性考虑的。在此强调,这个结构中重要的是结构的大小至少要求16字节,每个具体的成员的大小,请到你的系统中去察看,这里不再赘述。
需要说明的是:在实际的网络通讯中,该结构并不参与通信,尽管成员sin_port和sin_addr用在不同主机间的通信中。
IPv6的定义:
struct in6_addr {
unit8_t s6_addr[16];
};
#define SIN6_LEN
struct sockaddr_in6{
unit8_t sin6_len;
sa_family_t sin6_family;
in_port_t sin6_port;
unit32_t sin6_flowinfo;
struct in6_addr sin6_addr;

};
该结构比较特殊的是成员sin6_flowinfo,事实上该成员的32位用来表示不同的含义,如流量控制(低24位)、优先级(下4位)等。
以上所定义的结构,在我们实际的网络编程中,往往要作为某一个套接口函数的参数来使用,由于历史的原因和为了消除特定协议之间的差别,引入了所谓的通用套接口地址结构,定义如下:
struct sockaddr {
unit8_t sa_len;
sa_family_t sa_family;
char sa_data[14];
};
该结构一般的定义在/usr/include/sys/socket.h中,并且在很多系统中套接口函数原型的定义也使用该通用结构,如 int bind(int s, const struct sockaddr *addr, socklen_t addrlen);,这样在我们编写程序的时候,需要将只想特定协议的地址结构的指针类型转化为该通用套接口地址结构,例如:
struct sockaddr_in testserv;
/* other code */
if( ( ret = connect( sockfd, (struct sockaddr * )&amp;testserv,sizeof( testserv ) ) ) < 0 ) {
close(sockfd);
if( errno == EINTR ) {
errno = ETIMEDOUT;
continue;
}
}
/* other code */
以上简单的描述了IPb4和IPv6地址结构之间的差别,以及通用地址结构的使用。

有关两者互操作的下次补充(我要休息了,累!)
作者: gadfly    时间: 2003-04-03 00:15
标题: *******网络编程基础( 讨论版V1 )*******
原帖由 "蓝色键盘" 发表:

感谢gadfly对状态转化图的引入,不知道gadfly能否就TIME_WAIT和CLOE_WAIT和FIN_WAIT_1这三种状态做些描述,建议主要针对以下两方面来做描述:
(1)、该状态在什么情况下出现。
(2)、TCP为什么要引入该状态,分别对应与那些处理细节


我就试着用上图解释,错了不要拍砖啊. 请各位纠正和补充。

正常情况下,
主动关闭的一端发出FIN请求后(close or shotdown),主动关闭的一端就进入这个状态,
FIN-WAIT-1 - 等待远程TCP的连接中断请求,或先前的连接中断请求的确认;


被动关闭的一方接到FIN后,就发出ACK,并进入
CLOSE-WAIT - 等待足够的时间以确保远程TCP接收到连接中断请求的确认;

被动关闭的一方接着又发送FIN包,就进入了
LAST-ACK - 等待原来发向远程TCP的连接中断请求的确认;

主动关闭的一方接到ACK后,就进入了
FIN-WAIT-2 - 从远程TCP等待连接中断请求;

在主动的一方接收到FIN后,就发送ACK包,并进入TIME-WAIT状态。2MSL后进入closed

被动一方在接受到ACK包后,就进入了closed的状态。


TIME_WAIT状态状态也称为2MSL等待状态。MSL是TCP报文的生存时间,这样可让TCP再次发送最后的ACK以防这个ACK丢失(加入丢失,另一端超时并重发最后的FIN)。设想一下,
如果这个状态时间不足够长,如果ACK丢失,同时主动方的这个端口又重用了,对方因为
没有收到FIN的ACK,所以就重发FIN,有可能导致主动方连接的错误关闭。

如果是服务器被终止,并试图立即重新启动这个服务器程序的话,就可能发生经常出现的错误:can't bind local address: address already in use. 就是因为端口处于TIME_WAIT状态。不过可以通过设置选项SO_REUSEADDR来避免这种错误。


如果想了解的更透彻一些,建议通读TCP/IP详解 卷一的18章.
作者: 无双    时间: 2003-04-03 12:38
标题: *******网络编程基础( 讨论版V1 )*******
大家都讨论得很激烈
看来论坛中还是藏龙卧虎之地很不错

另外
如果client发送的数据被路由丢弃或者服务器的应答信息丢失,那么client将一直阻塞,直到应用设置的超时到达

我觉得UDP就是发送以后不管的
只是向UDP端口写完数据后就返回
不会等待是不是发送成功
作者: 蓝色键盘    时间: 2003-04-03 13:11
标题: *******网络编程基础( 讨论版V1 )*******
client在sendto后,需要recvfrom(除非你的这个UDP应用只发送数据不接收数据),对于服务端来的响应信息client是一直阻塞的(除非应用设置了超时),因而不论是client发送的数据被路由丢弃还是服务器的应答信息丢失,client都无法得知这些信息,这种情况对于异步错误也是一样的。
作者: gadfly    时间: 2003-04-03 13:35
标题: *******网络编程基础( 讨论版V1 )*******
原帖由 "无双" 发表:

我觉得UDP就是发送以后不管的
只是向UDP端口写完数据后就返回
不会等待是不是发送成功


同意你的观点,研究了一下,udp的输出队列有数据后,就会放到interface的
buf中,如果interface的buf满了,至少在linux上的处理是直接丢弃(参看sendto 的man ENOBUFS,和TCP/IP详解1的23)。在windows上缺省的buf满后,倒是会阻塞并等待。

而输入队列也有这个问题。如果发送方过快,即使数据到达对方主机,如果输入buf慢的话,udp包也是会丢失的。
作者: gadfly    时间: 2003-04-03 13:39
标题: *******网络编程基础( 讨论版V1 )*******
[quote]原帖由 "蓝色键盘"]client在sendto后,需要recvfrom(除非你的这个UDP应用只发送数据不接收数据),对于服务端来的响应信息client是一直阻塞的(除非应用设置了超时),因而不论是client发送的数据被路由丢弃还是服务器的应答信息丢失?.........[/quote 发表:



如果你这么说,只是说recvfrom会阻塞,而不是指sendto调用.

我想我和无双指的都是单个的sendto系统调用.
作者: 蓝色键盘    时间: 2003-04-03 14:01
标题: *******网络编程基础( 讨论版V1 )*******
对于sendto而言,是非阻塞的,如果发送的msg为0,它也能够成功,这时候发送的仅仅是一个IP头部和一个UDP头和一个空的数据报,即使在sendto中没有指明bind的IP和PORT,UDP会让系统来选择一个localhost和随机的Port填充结构 const struct sockaddr *to。
作者: 蓝色键盘    时间: 2003-04-03 14:15
标题: *******网络编程基础( 讨论版V1 )*******
对于recvfrom而言,是阻塞的(除非设置超时),unix95中原型如下:
ssize_t recvfrom( int  s,void  *buf,size_t  len,int  flags,struct sockaddr *from,size_t  *fromlen)
和sendto返回类型一样,recvfrom返回的是接受到的数据报大小。参数from和fromlen可以指定,也可以不指定,如果指定那么UDP用它来标识数据报的发送者是谁。该函数是从接受缓冲区接受数据报(如果缓冲区有数据报的话),如果RECVBUF没有数据,那么将阻塞。
作者: gadfly    时间: 2003-04-03 14:22
标题: *******网络编程基础( 讨论版V1 )*******
上面的关闭序列中,我只是列举了单方主动关闭的情况.

大家还可以研究一下双方同时主动关闭,以及单方半关闭的情况,这样能更好的理解shutdown,close的实现机制
作者: 蓝色键盘    时间: 2003-04-03 18:01
标题: *******网络编程基础( 讨论版V1 )*******
上面的5个问题只有4缺少完整讨论,这个留给其他的兄弟吧!总不能就我们几个说来说去,呵呵
接下来,谈论第二版V2。
作者: 无双    时间: 2003-04-03 18:03
标题: *******网络编程基础( 讨论版V1 )*******
如果是经常进行TCP/IP编程的话
研究深层理论还是很不错的
这样可以了解和使用socket的高级功能
如setsockopt等

如果调用shutdown的话,那么被shutdown端的的端口内数据会全部丢弃
端口关闭

这点和ckose不同
close是直到把端口内数据全部发送完后才关闭端口的

不知是不是这样
作者: gadfly    时间: 2003-04-03 18:25
标题: *******网络编程基础( 讨论版V1 )*******
shutdown有几种模式,但是与close最主要的区别在于它是半关闭.

SHUT_RD: 这个时候系统会关闭读通道.但是可以继续往接字描述符写
SHUT_WR:关闭写通道,和上面相反,着时候就只可以读了.
SHUT_RDWR: 关闭读写通道,和close一样 但是在多进程程序里面,如果有几个子进程共享一个套接字时,如果我们使用shutdown, 那么所有的子进程都不能够操作了,这个时候我们只能够使用close来关闭子进程的套接字描述符.  

这种半关闭模式,在rsh里面有应用
考虑rsh remote_host sort <data

在datafile输入完成后,执行这个tcp连接写的半关闭.但是可以继续接受对方发过来的结果

http://www.fanqiang.com/a4/b7/20010508/112209.html
作者: 无双    时间: 2003-04-03 18:36
标题: *******网络编程基础( 讨论版V1 )*******
shutdown全关闭好像中直接清空缓冲区,和close不同
这点在UNIX网络编程上有比较


close只是减少引用数
等到引用数为0时才真正关闭
作者: gadfly    时间: 2003-04-03 19:02
标题: *******网络编程基础( 讨论版V1 )*******
原帖由 "gadfly" 发表:


SHUT_RDWR: 关闭读写通道,和close一样 但是在多进程程序里面,如果有几个子进程共享一个套接字时,如果我们使用shutdown, 那么所有的子进程都不能够操作了,这个时候我们只能够使用close来关闭子进程的套接字描述符.

原帖由 "无双" 发表:

shutdown全关闭好像中直接清空缓冲区,和close不同
这点在UNIX网络编程上有比较


close只是减少引用数
等到引用数为0时才真正关闭


和我上面列举的并不矛盾.是可以相互解释的

可以这样理解, 多进程来共享socket连接时,
shutdown清空缓冲区(共享的),同时将socket关闭.

正因为close是通过引用计数来关闭,所以多进程共享的情况下,用close来关闭比较安全.
作者: 无双    时间: 2003-04-03 19:12
标题: *******网络编程基础( 讨论版V1 )*******
我说的主要区别是使用shutdown时缓冲区会清空

但是close时不会清空,只有缓冲区内数据全部发送后才关闭
作者: 无双    时间: 2003-04-03 19:14
标题: *******网络编程基础( 讨论版V1 )*******
这点是很久以前在UNIX网络编程
上看到的,但应该是这样

使用shutdown的话,因为数据缓冲区被清空,所以没有发送的内容会丢掉
一般是很少用
而使用close更安全一点
作者: 蓝色键盘    时间: 2003-04-03 20:34
标题: *******网络编程基础( 讨论版V1 )*******
对于close来说,默认行为是努力将发送缓冲区的残留数据发送完。该行为可以通过选项SO_LINGER来改变,如果由兴趣的话,我们可以专门来讨论改选项。cloes调用一次,只是将描述字的访问次数-1,仅当且当该次数为0的时候才真正的关闭socket。从关闭的角度看close是同时关闭read和write,而shutdown可以根据需要关闭read或write或两者。

对于shutdown来说,它的行为是通过三个宏来确定的,对于SHUT_RD来说,接受缓冲区的数据是要被清空的。而宏SHUT_WR一旦设置,sockets拒绝任何write操作,但是不清空发送缓冲区的内容,这点,gadfly的描述是不正确的。对于宏SHUT_RDWR来说,行为是接受缓冲区的数据被清空,发送缓冲区的内容不清空。
作者: gadfly    时间: 2003-04-03 23:11
标题: *******网络编程基础( 讨论版V1 )*******
我前一个说明shutdown只是针对全关闭(SHUT_RDWR)而言的.
而宏SHUT_WR一旦设置,sockets拒绝任何write操作,但是不清空发送缓冲区的内容,这点,gadfly的描述是不正确的。对于宏SHUT_RDWR来说,行为是接受缓冲区的数据被清空,发送缓冲区的内容不清空。


这个恐怕得依赖于kernel的实现,你可以看看这个url:
http://www.gnu.org/manual/glibc-2.2.5/html_node/Closing-a-Socket.html#Closing%20a%20Socket

int shutdown (int socket, int how)  Function
The shutdown function shuts down the connection of socket socket. The argument how specifies what action to perform:
0
Stop receiving data for this socket. If further data arrives, reject it.

1
Stop trying to transmit data from this socket. Discard any data waiting to be sent. Stop looking for acknowledgement of data already sent; don't retransmit it if it is lost.

2
Stop both reception and transmission.

从gnu的文档中,可以看到,是立即放弃缓存中的数据的.
但是有的也说linux kernel的实现是不清空,继续发送,并且不受so_linger影响

无论如何,和close的作用相比,我想,shutdown的最大作用是用于半关闭,而close是无法做到的,全关闭这种方式基本上用不到.
作者: gadfly    时间: 2003-04-03 23:13
标题: *******网络编程基础( 讨论版V1 )*******
http://www.softlab.ece.ntua.gr/facilities/documentation/unix/unix-socket-faq/unix-socket-faq-2.html#ss2.6

When should I use shutdown()?
From Michael Hunter ( mphunter@qnx.com):

shutdown() is useful for deliniating when you are done providing a request to a server using TCP. A typical use is to send a request to a server followed by a shutdown(). The server will read your request followed by an EOF (read of 0 on most unix implementations). This tells the server that it has your full request. You then go read blocked on the socket. The server will process your request and send the necessary data back to you followed by a close. When you have finished reading all of the response to your request you will read an EOF thus signifying that you have the whole response. It should be noted the TTCP (TCP for Transactions -- see R. Steven's home page) provides for a better method of tcp transaction management.

大概的意思是利用shutdown的半关闭特性,实现tcp的事务管理.
作者: 无双    时间: 2003-04-04 08:43
标题: *******网络编程基础( 讨论版V1 )*******
shutdown 函数
close有两个限制可由函数shutdown来避免:

close将描述字的访问计数减1,仅在此计数为0时才关闭套接口
shutdown可激发TCP的正常连接终止序列, 而不管访问计数。
这里的内容还是比较有用的,以前一直没有注意

close终止了数据传送的两个方向:读和写。
shutdown终止的数据传送的两个方向:读和写, 或其中任一方向:读或写

定义:
int shutdown( int sockfd, int howto) ;

howto选项:
SHUT_RD 关闭连接的读一半
SHUT_WR 关闭连接的写这一半
SHUT_RDWR 关闭连接读读和写
作者: wmjwl    时间: 2003-04-04 10:52
标题: *******网络编程基础( 讨论版V1 )*******
经典!通俗易懂!谢了!
作者: 蓝色键盘    时间: 2003-04-04 11:25
标题: *******网络编程基础( 讨论版V1 )*******
请继续关注,马上将要进行第二版V2的讨论。
作者: hjzgq    时间: 2003-05-06 14:22
标题: *******网络编程基础( 讨论版V1 )*******
很好,大有收获!
作者: rdd    时间: 2003-05-09 20:26
标题: *******网络编程基础( 讨论版V1 )*******
4、TCP的三路握手和四分组连接终止序列的过程分别是什么
作者: rdd    时间: 2003-05-09 20:49
标题: *******网络编程基础( 讨论版V1 )*******
4、TCP的三路握手和四分组连接终止序列的过程分别是什么
三路握手:
下述步骤建立一个tcp连结:
1)服务器必须准备好接受外来的连接。这通过调用socket,bind,listen函数来完成,成为被动打开(passive open).
2)客户通过调用connect进行主动打开(active open).这引起客户tcp发送一个SYN分节(表示同步),它告诉服务器客户将在(待建立的)连接中发送的数据的初始序列号。一般情况下syn分节不携带数据,它只含有一个ip头部、一个tcp 头部以及可能有的tcp选项。
3)服务器必须确认客户的syn,同时自己也得发送一个syn分节,它含有服务器将在同一连接中发送的数据的初始序列号。服务器以单个分节向客户发送syn和对客户syn的ack.
4)客户必须确认服务器的syn.
l连接建立过程至少需要交换三个分组,因此称之为tcp的三路握手(three-way hand shake).
TCP连接终止:
1)某个应用进程首先调用close,我们称这一端主动关闭(active close).这一端的tcp于是发送一个FIN分节,表示数据发送完毕。
2)接收到FIN的另一端执行被动关闭(PASSIVE CLOSE).这个FIN由TCP确定。它的接收也作为文件结束符传递给接收方应用进程(放在已经排队等候该应用进程接收的任何其他数据之后),因为FIN的接收意味着应用进程在相应连接上再也接受不到额外数据。
3)一段时间后,接收到文件结束符的应用进程将调用CLOSE关闭它的套接口。这导致它的TCP也发送一个 FIN
4)接收到这个FIN的原发送方TCP(即执行主动关闭的那一端)对它进行确认。
因为每个方向都需要有一个FIN和一个ACK,所以一般需要四个分节。

大家可以监视一个FTP连接来察看,WIN2K下用网络监视器,LINUX和UNIX下可以用TCPDUMP等。
作者: shangxd    时间: 2003-05-09 21:59
标题: *******网络编程基础( 讨论版V1 )*******
期待V2的讨论。
建议开一个IRC聊天室,方便讨论。
作者: shangxd    时间: 2003-05-11 11:50
标题: *******网络编程基础( 讨论版V1 )*******
顶一下!
作者: 蓝色键盘    时间: 2003-05-12 10:12
标题: *******网络编程基础( 讨论版V1 )*******
期待V2的讨论。

V2做了部分的讨论,可以查找一下,各位可以发表自己的看法,给予回复!
作者: 蓝色键盘    时间: 2003-05-12 10:15
标题: *******网络编程基础( 讨论版V1 )*******
感谢rdd对于
4、TCP的三路握手和四分组连接终止序列的过程分别是什么

让这个讨论更精确。在此感谢!
作者: cdr7606    时间: 2003-05-12 10:50
标题: *******网络编程基础( 讨论版V1 )*******
在这里看到各位高手的讨论,佩服已极。目前小弟我遇到一个比较典型的问题,不知可否请教各位,并期望找到答案:
  通讯的SERVER端应用程序在被动关闭时有时会进入CLOSE_WAIT状态,并导致端口不可用,能否对于CLOSE_WAIT进行更为详细的讨论或答疑。
作者: 无双    时间: 2003-05-12 13:05
标题: *******网络编程基础( 讨论版V1 )*******
FAQ
作者: unixsc    时间: 2007-02-23 18:13
不错.理解.
作者: unixsc    时间: 2007-02-23 18:24
原帖由 gadfly 于 2003-4-3 00:15 发表


我就试着用上图解释,错了不要拍砖啊. 请各位纠正和补充。

正常情况下,
主动关闭的一端发出FIN请求后(close or shotdown),主动关闭的一端就进入这个状态,
FIN-WAIT-1 - 等待远程TCP的连接中断请求 ...


"智商相当高"
作者: aobai    时间: 2007-04-07 07:16
标题: 回复 13楼 无双 的帖子
由于client端的端口号是随机分配的.连续两次连接出现重号的几率是不是非常小,大概为多少?




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2