发信人: lunarsea()
整理人: workingnow(2002-10-30 13:58:37), 站内信件
|
第五帖 基本套接字调用--建立套接字连接connect()与accept()
这两个系统调用用于完成一个全相关的建立,其中connect()用于
建立连接。accept()使服务器等待来自某客户进程的实际连接。
其调用格式如下
connect(SOCKET sockid,struct sockaddr* destaddr,int addrlen);
//sockid是欲建立连接的本地socket号
//destaddr是一个指向对方socket地址(信宿地址)结构的指针
//addrlen是对方socket地址长度
perl语言的connect()调用格式为:
connect(SOC_VARIABLE,NAME_VARIABLE)
具体的调用过程如下
$remoteaddr_port = sockaddr_in($port,inet_aton('abc.efg.com'));
connect(CLIENT,$remoteaddr_port); #半相关三元组(协议,远地地址,远地端
口号)
可以发现connect()和bind()调用如出一辙,只是SERVER换成CLIENT,
local换成remote,没错,他们的道理是一样的,作用是互补的。他们各
自建立了服务器和客户机方面的半相关。这时就要accept()来掺和一下
一个完整的网间进程通信的全相关就可以建立啦!
(其实标准connect()还可以用于无连接的socket调用。但这个用法比较
左道,常把人搞晕点,所以就不说了)
标准accept()调用:
SOCKET newsock = accept(SOCKET sockid,struct sockaddr* clientaddr,int
addlen)
//sockid ,服务器本地的socket号
//clientaddr ,指向客户socket结构的指针。它的初始值为空
//addlen ,客户socket结构的字节长度,它的初始值为0
//newsock ,accept()的返回值,为一个新的socket号,可用于服务器
//处理并发请求。服务器fork一个子服务器进程,利用此socket号回
//答accept()所接收的客户请求
可以看出,accept()是面向连接的服务器端的调用。他还将客户端的
socket地址及其字节长度放在clientaddr和addlen以便为其他无连接的
调用指定信宿地址。但是,那些比较灵活但没有原则的无连接用法在
perl里是没有的,perl的用法认为socket必须是面向连接的,请看perl
里的accept():
accept(NEW_SOC_VARIABLE,CURRENT_SOC_VARIABLE);
可以看到accept()从当前的socket句柄上连接出一个客户端到新的
socket句柄。而它的返回值客户端的地址(信宿地址)。其实连接一旦建
立,服务方无须知道信宿地址,只要向套口里灌输比特流就行了。这样做
的好处是使协议对于应用程序更加透明,易于理解。
在调用accept()之前还应该先调用listen(),(不要骂我,我一不小心就
忘了顺序啦,实在对不起----啊!臭鸡蛋,谁扔的?!)listen()的作用
是侦听端口,接收连接。如果不调用listen()的话,accept()将无法从
当前socket"接"回与客户端的连接。标准listen():
listen(sockid,quelen);
//socket号,服务器愿意从它上面接收请求
//quelen,请求队列长度,listen()以此限制排队请求的个数
perl的listen():
listen(SOC_VARIABLE,num);#和C语言的版本很像哦
SOC_VARIABLE是socket句柄,num是请求队列长度.
到这里为止,一个连接的五元组都齐了。有关连接事宜算是搞定。
下回就可以传数据了。
(未完待续...)
-- 无边无际的黑暗与冰冷,湮灭了黎明的曙光,向着你
扑 面 而 来!
※ 修改:.lunarsea 于 Jul 9 08:42:46 修改本文.[FROM: 202.100.27.169] ※ 来源:.月光软件站 http://www.moon-soft.com.[FROM: 202.100.29.101]
|
|