??xml version="1.0" encoding="utf-8" standalone="yes"?>99国内精品久久久久久久,久久精品视频91,久久国产高清一区二区三区http://m.shnenglu.com/yunboy4/category/11310.htmlC++zh-cnThu, 30 Jul 2009 06:31:22 GMTThu, 30 Jul 2009 06:31:22 GMT60setsockopt参数详细说明(转蝲)http://m.shnenglu.com/yunboy4/archive/2009/07/29/91551.htmlyunboyyunboyWed, 29 Jul 2009 00:33:00 GMThttp://m.shnenglu.com/yunboy4/archive/2009/07/29/91551.htmlhttp://m.shnenglu.com/yunboy4/comments/91551.htmlhttp://m.shnenglu.com/yunboy4/archive/2009/07/29/91551.html#Feedback0http://m.shnenglu.com/yunboy4/comments/commentRss/91551.htmlhttp://m.shnenglu.com/yunboy4/services/trackbacks/91551.html

int setsockopt(
  SOCKET s,
  int level,
  int optname,
  const char* optval,
  int optlen
);

s(套接?: 指向一个打开的套接口描述?
 level:(U别)Q?#160;指定选项代码的类型?
SOL_SOCKET: 基本套接?#160;
IPPROTO_IP: IPv4套接?#160;
IPPROTO_IPV6: IPv6套接?#160;
IPPROTO_TCP: TCP套接?#160;
optname(选项?Q?#160;选项名称 
optval(选项?: 是一个指向变量的指针 cdQ整形,套接口结构, 其他l构cd:linger{}, timeval{ } 
optlen(选项长度) Qoptval 的大?#160;

q回|标志打开或关闭某个特征的二进刉项
[/code:1:59df4ce128]

 

======================================================================== 
SOL_SOCKET 
------------------------------------------------------------------------ 
SO_BROADCAST 允许发送广播数?#160;int 
适用?#160;UDP socket。其意义是允?#160;UDP socket 「广播」(broadcastQ讯息到|\上?

SO_DEBUG 允许调试 int 

SO_DONTROUTE 不查找\?#160;int 

SO_ERROR 获得套接字错?#160;int 

SO_KEEPALIVE 保持q接 int 
对方主机是否崩溃,避免Q服务器Q永q阻塞于TCPq接的输入?#160;讄该选项后,如果2时内在此套接口的Q一方向都没有数据交换,TCPp动给Ҏ 发一个保持存zL分?keepalive probe)。这是一个对方必d应的TCP分节.它会D以下三种情况Q?#160;Ҏ接收一切正常:以期望的ACK响应?时后,TCP发出另一个探分节?#160;Ҏ已崩溃且已重新启动:以RST响应。套接口的待处理错误被置为ECONNRESETQ套?#160;口本w则被关闭?#160;Ҏ无Q何响应:源自berkeley的TCP发送另?个探分节,盔R75U一个,试图得到 一个响应。在发出W一个探分?1分钟15U后若仍无响应就攑ּ。套接口的待处理?#160;误被|ؓETIMEOUTQ套接口本n则被关闭。如ICMP错误?#8220;host unreachable(L?#160;可达)”Q说明对方主机ƈ没有崩溃Q但是不可达Q这U情况下待处理错误被|ؓ EHOSTUNREACH?#160;



SO_DONTLINGER 若ؓ真,则SO_LINGER选项被禁止?
SO_LINGER 延迟关闭q接 struct linger 
上面q两个选项影响close行ؓ
选项 间隔 关闭方式 {待关闭与否
SO_DONTLINGER 不关?#160;优雅 ?
SO_LINGER ?#160;强制 ?
SO_LINGER 非零 优雅 ?
若设|了SO_LINGERQ亦即lingerl构中的l_onoff域设为非Ӟ参见2.4Q?.1.7?.1.21各节Q,q设|了零超旉隔,则closesocket()不被d立即执行Q不论是否有排队数据未发送或未被认。这U关闭方式称?#8220;强制”?#8220;失效”关闭Q因为套接口的虚电\立即被复位,且丢׃未发送的数据。在q端的recv()调用以WSAECONNRESET出错?
若设|了SO_LINGERq确定了非零的超旉隔,则closesocket()调用dq程Q直到所剩数据发送完毕或时。这U关闭称?#8220;优雅?#8221;关闭。请注意如果套接口置为非d且SO_LINGER设ؓ非零时Q则closesocket()调用以WSAEWOULDBLOCK错误q回?
若在一个流cd接口上设|了SO_DONTLINGERQ也是说将lingerl构的l_onoff域设为零Q参?.4Q?.1.7Q?.1.21节)Q则closesocket()调用立即q回。但是,如果可能Q排队的数据在套接口关闭前发送。请注意Q在q种情况下WINDOWS套接口实现将在一D不定的时间内保留套接口以及其他资源,q对于想用所以套接口的应用程序来说有一定媄响?



SO_OOBINLINE 带外数据攑օ正常数据?在普通数据流中接收带外数?#160;int 

SO_RCVBUF 接收~冲区大?#160;int 
讄接收~冲区的保留大小
?#160;SO_MAX_MSG_SIZE 或TCP滑动H口无关Q如果一般发送的包很大很频繁Q那么用这个选项

SO_SNDBUF 发送缓冲区大小 int 
讄发送缓冲区的保留大?
?#160;SO_MAX_MSG_SIZE 或TCP滑动H口无关Q如果一般发送的包很大很频繁Q那么用这个选项
每个套接口都有一个发送缓冲区和一个接收缓冲区?#160;接收~冲TCP和UDP用来接收到的数据一直保存到由应用进E来诅R?#160;TCPQTCP通告另一端的H口大小?#160;TCP套接口接收缓冲区不可能溢出,因ؓҎ不允许发q所通告H口大小的数据?#160;q就是TCP的流量控Ӟ如果Ҏ无视H口大小而发Z过宙口大小的数据,则接 收方TCP丢弃它?#160;UDPQ当接收到的数据报装不进套接口接收缓冲区Ӟ此数据报p丢弃。UDP是没?#160;量控制的;快的发送者可以很Ҏ地就Ҏ慢的接收者,D接收方的UDP丢弃数据报?



SO_RCVLOWAT 接收~冲Z?#160;int 
SO_SNDLOWAT 发送缓冲区下限 int 
每个套接口都有一个接收低潮限度和一个发送低潮限度。它们是函数selectt使用的, 接收低潮限度是让selectq回“可读”而在套接口接收缓冲区中必L的数据总量?#160;——对于一个TCP或UDP套接口,此值缺省ؓ1。发送低潮限度是让selectq回“可写” 而在套接口发送缓冲区中必L的可用空间。对于TCP套接口,此值常~省?048?#160;对于UDP使用低潮限度Q?#160;׃其发送缓冲区中可用空间的字节数是从不变化的,只要 UDP套接口发送缓冲区大小大于套接口的低潮限度Q这LUDP套接口就L可写的?#160;UDP没有发送缓冲区Q只有发送缓冲区的大?

SO_RCVTIMEO 接收时 struct timeval 
SO_SNDTIMEO 发送超?#160;struct timeval 
SO_REUSERADDR 允许重用本地地址和端?#160;int 
充许l定已被使用的地址Q或端口PQ可以参考bind的man

SO_EXCLUSIVEADDRUSE
独占模式使用端口,是不充许和其它E序使用SO_REUSEADDR׃n的用某一端口?
在确定多重绑定用谁的时候,Ҏ一条原则是谁的指定最明确则将包递交l谁Q而且没有权限之分Q也是说低U权限的用户是可以重l定在高U权限如服务启动的端口上?q是非常重大的一个安全隐?
如果不想让自q序被监听Q那么用这个选项

SO_TYPE 获得套接字类?#160;int 
SO_BSDCOMPAT 与BSDpȝ兼容 int 











========================================================================== 
IPPROTO_IP 
-------------------------------------------------------------------------- 
IP_HDRINCL 在数据包中包含IP首部 int 
   q个选项常用于黑客技术中Q隐藏自qIP地址

IP_OPTINOS IP首部选项 int 
IP_TOS 服务cd 
IP_TTL 生存旉 int 

以下IPV4选项用于l播
IPv4 选项 数据cd ?#160;q?
  IP_ADD_MEMBERSHIP struct ip_mreq 加入到组播组?
  IP_ROP_MEMBERSHIP struct ip_mreq 从组播组中退?
  IP_MULTICAST_IF struct ip_mreq 指定提交l播报文的接?
  IP_MULTICAST_TTL u_char 指定提交l播报文的TTL
  IP_MULTICAST_LOOP u_char 使组播报文环路有效或无效
在头文g中定义了ip_mreql构Q?
[code:1:63724de67f]
struct ip_mreq {
struct in_addr imr_multiaddr; /* IP multicast address of group */
struct in_addr imr_interface; /* local IP address of interface */
};
[/code:1:63724de67f]
若进E要加入C个组播组中,用soket的setsockopt()函数发送该选项。该选项cd是ip_mreql构Q它的第一个字Dimr_multiaddr指定了组播组的地址Q第二个字段imr_interface指定了接口的IPv4地址?
  IP_DROP_MEMBERSHIP
  该选项用来从某个组播组中退出。数据结构ip_mreq的用方法与上面相同?
  IP_MULTICAST_IF
  该选项可以修改|络接口Q在l构ip_mreq中定义新的接口?
  IP_MULTICAST_TTL
  讄l播报文的数据包的TTLQ生存时_。默认值是1Q表C数据包只能在本地的子网中传送?
  IP_MULTICAST_LOOP
  l播l中的成员自׃会收到它向本l发送的报文。这个选项用于选择是否Ȁz这U状态?br>

 无双 回复于:2003-05-08 21:21:52

IPPRO_TCP 
-------------------------------------------------------------------------- 
TCP_MAXSEG TCP最大数据段的大?#160;int 
获取或设|TCPq接的最大分节大?MSS)。返回值是我们的TCP发送给另一端的最?#160;数据量,它常常就是由另一端用SYN分节通告的MSSQ除非我们的TCP选择使用一个比 Ҏ通告的MSS些的倹{如果此值在套接口连接之前取得,则返回gؓ未从?#183;—端 收到Mss选项的情况下所用的~省倹{小于此q回值的信可能真正用在连接上Q因 如说使用旉戳选项的话Q它在每个分节上占用12字节的TCP选项定w。我们的TcP?#160;发送的每个分节的最大数据量也可在连接存zL内改变,但前提是TCP要支持\径MTU 发现功能。如果到Ҏ的\径改变了Q此值可上下调整?
TCP_NODELAY 不用Nagle法 int 

指定TCP开始发送保持存zL分节前以秒为单位的q接I闲旉。缺省D必Mؓ7200U,?时。此选项仅在SO_KEPALIVEE套接口选项打开时才有效?

TCP_NODELAY ?#160;TCP_CORKQ?
q两个选项都对|络q接的行为具有重要的作用。许多UNIXpȝ都实CTCP_NODELAY选项Q但是,TCP_CORK则是Linuxpȝ所独有的而且相对较新Q它首先在内核版?.4上得以实现。此外,其他UNIXpȝ版本也有功能cM的选项Q值得注意的是Q在某种由BSDz的系l上的TCP_NOPUSH选项其实是TCP_CORK的一部分具体实现?
TCP_NODELAY和TCP_CORK基本上控制了包的“Nagle?#8221;QNagle化在q里的含义是采用Nagle法把较的包组装ؓ更大的。John Nagle是Nagle法的发明hQ后者就是用他的名字来命名的Q他?984q首ơ用q种Ҏ来尝试解决福Ҏ车公司的|络拥塞问题Q欲了解详情请参看IETF RFC 896Q。他解决的问题就是所谓的silly window syndrome Q中文称“愚蠢H口症候群”Q具体含义是Q因为普遍终端应用程序每产生一ơ击键操作就会发送一个包Q而典型情况下一个包会拥有一个字节的数据载荷以及40个字节长的包_于是产生4000%的过载,很轻易地p令网l发生拥??#160;Nagle化后来成了一U标准ƈ且立卛_因特|上得以实现。它现在已经成ؓ~省配置了,但在我们看来Q有些场合下把这一选项x也是合乎需要的?
现在让我们假设某个应用程序发Z一个请求,希望发送小块数据。我们可以选择立即发送数据或者等待生更多的数据然后再一ơ发送两U策略。如果我们马上发送数据,那么交互性的以及客户/服务器型的应用程序将极大地受益。例如,当我们正在发送一个较短的hq且{候较大的响应Ӟ相关q蝲与传输的数据总量相比׃比较低,而且Q如果请求立卛_出那么响应时间也会快一些。以上操作可以通过讄套接字的TCP_NODELAY选项来完成,q样q用了Nagle法?
另外一U情况则需要我们等到数据量辑ֈ最大时才通过|络一ơ发送全部数据,q种数据传输方式有益于大量数据的通信性能Q典型的应用是文g服务器。应用Nagle法在这U情况下׃产生问题。但是,如果你正在发送大量数据,你可以设|TCP_CORK选项用Nagle化,其方式正好同TCP_NODELAY相反QTCP_CORK ?#160;TCP_NODELAY 是互相排斥的Q。下面就让我们仔l分析下其工作原理?
假设应用E序使用sendfile()函数来{Ud量数据。应用协议通常要求发送某些信息来预先解释数据Q这些信息其实就是报头内宏V典型情况下报头很小Q而且套接字上讄了TCP_NODELAY。有报头的包被立即传输Q在某些情况下(取决于内部的包计数器Q,因ؓq个包成功地被对Ҏ到后需要请求对方确认。这P大量数据的传输就会被推迟而且产生了不必要的网l流量交换?
但是Q如果我们在套接字上讄了TCP_CORKQ可以比Mؓ在管道上插入“塞子”Q选项Q具有报头的包就会填补大量的数据Q所有的数据都根据大自动地通过包传输出厅R当数据传输完成Ӟ最好取消TCP_CORK 选项讄l连?#8220;拔去塞子”以便M部分的都能发送出厅R这?#8220;塞住”|络q接同等重要?
总而言之,如果你肯定能一起发送多个数据集合(例如HTTP响应的头和正文)Q那么我们徏议你讄TCP_CORK选项Q这样在q些数据之间不存在gq。能极大地有益于WWW、FTP以及文g服务器的性能Q同时也化了你的工作。示例代码如下:

intfd, on = 1;

/* 此处是创建套接字{操作,Z幅的考虑省略*/

setsockopt (fd, SOL_TCP, TCP_CORK, &on, sizeof (on)); /* cork */
write (fd, …);
fprintf (fd, …);
sendfile (fd, …);
write (fd, …);
sendfile (fd, …);

on = 0;
setsockopt (fd, SOL_TCP, TCP_CORK, &on, sizeof (on)); /* 拔去塞子 */


不幸的是Q许多常用的E序q没有考虑C上问题。例如,Eric Allman~写的sendmail没有对其套接字讄M选项?

Apache HTTPD是因特网上最行的Web服务器,它的所有套接字都讄了TCP_NODELAY选项Q而且其性能也深受大多数用户的满意。这是ؓ什么呢Q答案就在于实现的差别之上。由BSD衍生的TCP/IP协议栈(值得注意的是FreeBSDQ在q种状况下的操作׃同。当在TCP_NODELAY 模式下提交大量小数据块传输时Q大量信息将按照一ơwrite()函数调用发送一块数据的方式发送出厅R然而,因ؓ负责h交付认的记数器是面向字节而非面向包(在Linux上)的,所以引入gq的概率降低了很多。结果仅仅和全部数据的大有关系。?#160;Linux 在第一包到达之后就要求认QFreeBSD则在q行如此操作之前会等待好几百个包?

在Linuxpȝ上,TCP_NODELAY的效果同习惯于BSD TCP/IP协议栈的开发者所期望的效果有很大不同Q而且在Linux上的Apache性能表现也会更差些。其他在Linux上频J采用TCP_NODELAY的应用程序也有同L问题?


TCP_DEFER_ACCEPT

我们首先考虑的第1个选项是TCP_DEFER_ACCEPTQ这是Linuxpȝ上的叫法Q其他一些操作系l上也有同样的选项但用不同的名字Q。ؓ了理解TCP_DEFER_ACCEPT选项的具体思想Q我们有必要大致阐述一下典型的HTTP客户/服务器交互过E。请回想下TCP是如何与传输数据的目标徏立连接的。在|络上,在分ȝ单元之间传输的信息称为IP包(或IP 数据报)。一个包L一个携带服务信息的包头Q包头用于内部协议的处理Qƈ且它也可以携带数据负载。服务信息的典型例子是一套所谓的标志Q它把包标记代表TCP/IP协议栈内的特D含义,例如收到包的成功认{等。通常Q在l过“标记”的包里携带负载是完全可能的,但有Ӟ内部逻辑qTCP/IP协议栈发出只有包头的IP包。这些包l常会引发讨厌的|络延迟而且q增加了pȝ的负载,l果D|络性能在整体上降低?
现在服务器创Z一个套接字同时{待q接。TCP/IP式的q接q程是所?#8220;3ơ握?#8221;。首先,客户E序发送一个设|SYN标志而且不带数据负蝲的TCP包(一个SYN包)。服务器则以发出带SYN/ACK标志的数据包Q一个SYN/ACK包)作ؓ刚才收到包的认响应。客户随后发送一个ACK包确认收CW?个包从而结束连接过E。在收到客户发来的这个SYN/ACK包之后,服务器会唤醒一个接收进E等待数据到达。当3ơ握手完成后Q客L序即开始把“有用?#8221;的数据发送给服务器。通常Q一个HTTPh的量是很的而且完全可以装到一个包里。但是,在以上的情况下,臛_?个包用来进行双向传输,q样增加了可观的gq时间。此外,你还得注意到Q在“有用?#8221;数据被发送之前,接收方已l开始在{待信息了?
Z减轻q些问题所带来的媄响,LinuxQ以及其他的一些操作系l)在其TCP实现中包括了TCP_DEFER_ACCEPT选项。它们设|在侦听套接字的服务器方Q该选项命o内核不等待最后的ACK包而且在第1个真正有数据的包到达才初始化侦听q程。在发送SYN/ACK包之后,服务器就会等待客L序发送含数据的IP包。现在,只需要在|络上传?个包了,而且q显著降低了q接建立的gq,对HTTP通信而言其如此?
q一选项在好些操作系l上都有相应的对{物。例如,在FreeBSD上,同样的行为可以用以下代码实现Q?

/* 为明晰v见,此处略去无关代码 */
struct accept_filter_arg af = { "dataready", "" };
setsockopt(s, SOL_SOCKET, SO_ACCEPTFILTER, &af, sizeof(af));
q个特征在FreeBSD上叫?#8220;接受qo?#8221;Q而且h多种用法。不q,在几乎所有的情况下其效果与TCP_DEFER_ACCEPT是一LQ服务器不等待最后的ACK包而仅仅等待携带数据负载的包。要了解该选项及其寚w性能Web服务器的重要意义的更多信息请参考Apache文档上的有关内容?
HTTP客户/服务器交互而言Q有可能需要改变客L序的行ؓ。客L序ؓ什么要发送这U?#8220;无用?#8221;ACK包呢Q这是因为,TCP协议栈无法知道ACK包的状态。如果采用FTP而非HTTPQ那么客L序直到接收了FTP服务器提C的数据包之后才发送数据。在q种情况下,延迟的ACK导致客?服务器交互出现gq。ؓ了确定ACK是否必要Q客L序必ȝ道应用程序协议及其当前状态。这P修改客户行ؓ成为必要了?
对Linux客户E序来说Q我们还可以采用另一个选项Q它也被叫做TCP_DEFER_ACCEPT。我们知道,套接字分成两U类型,侦听套接字和q接套接字,所以它们也各自h相应的TCP选项集合。因此,l常同时采用的这两类选项却具有同L名字也是完全可能的。在q接套接字上讄该选项以后Q客户在收到一个SYN/ACK包之后就不再发送ACK包,而是{待用户E序的下一个发送数据请求;因此Q服务器发送的包也q应减了?

TCP_QUICKACK

L因发送无用包而引发gq的另一个方法是使用TCP_QUICKACK选项。这一选项?#160;TCP_DEFER_ACCEPT不同Q它不但能用作管理连接徏立过E而且在正常数据传输过E期间也可以使用。另外,它能在客?服务器连接的M一方设|。如果知道数据不久即发送,那么推迟ACK包的发送就会派上用场,而且最好在那个携带数据的数据包上设|ACK 标志以便把网l负载减到最。当发送方肯定数据被立即发送(多个包)ӞTCP_QUICKACK选项可以讄?。对处于“q接”状态下的套接字该选项的缺省值是1Q首ơ用以后内核将把该选项立即复位?Q这是个一ơ性的选项Q?
在某些情形下Q发出ACK包则非常有用。ACK包将认数据块的接收Q而且Q当下一块被处理时不至于引入延迟。这U数据传输模式对交互q程是相当典型的Q因为此cL况下用户的输入时L法预。在Linuxpȝ上这是~省的套接字行ؓ?
在上q情况下Q客L序在向服务器发送HTTPhQ而预先就知道h包很短所以在q接建立之后应该立卛_送,q可谓HTTP的典型工作方式。既然没有必要发送一个纯_的ACK包,所以设|TCP_QUICKACK?以提高性能是完全可能的。在服务器方Q这两种选项都只能在侦听套接字上讄一ơ。所有的套接字,也就是被接受呼叫间接创徏的套接字则会l承原有套接字的所有选项?
通过TCP_CORK、TCP_DEFER_ACCEPT和TCP_QUICKACK选项的组合,参与每一HTTP交互的数据包数量被降低到最的可接受水qIҎTCP协议的要求和安全斚w的考虑Q。结果不仅是获得更快的数据传输和h处理速度而且q客户/服务器双向gq实C最化?



yunboy 2009-07-29 08:33 发表评论
]]>
非阻塞套接字的模?/title><link>http://m.shnenglu.com/yunboy4/archive/2009/07/26/91231.html</link><dc:creator>yunboy</dc:creator><author>yunboy</author><pubDate>Sun, 26 Jul 2009 03:13:00 GMT</pubDate><guid>http://m.shnenglu.com/yunboy4/archive/2009/07/26/91231.html</guid><wfw:comment>http://m.shnenglu.com/yunboy4/comments/91231.html</wfw:comment><comments>http://m.shnenglu.com/yunboy4/archive/2009/07/26/91231.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.shnenglu.com/yunboy4/comments/commentRss/91231.html</wfw:commentRss><trackback:ping>http://m.shnenglu.com/yunboy4/services/trackbacks/91231.html</trackback:ping><description><![CDATA[<p> </p> <div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #000000">1</span><span style="COLOR: #000000">.非阻塞套接字的模?br>(</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">)服务器端<br>    通常socketq行后默认ؓd模式。要调用ioctlsocket函数讄非阻塞模式?br>如:<br><br>    WSAData Data;<br>    WSAStartup(MAKEWORD(</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">), </span><span style="COLOR: #000000">&</span><span style="COLOR: #000000">Data);<br>    SerSocket </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);<br>    </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(INVALID_SOCKET </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> SerSocket)<br>        cout</span><span style="COLOR: #000000"><<</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Invalid Socket!\n</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;<br>    u_long iMode </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">;<br>    ioctlsocket(SerSocket, FIONBIO, </span><span style="COLOR: #000000">&</span><span style="COLOR: #000000">iMode);<br>    <br>    在接受客Lh的线E中Q若接受成功p回客L的套接字Q否则返回INVALID_SOCKET错误Q?br>若错误代码ؓWSAEWOULDBLOCKQ说明当前没有客Lh?br>如:<br></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">接受客户端请求线E?/span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">DWORD WINAPI AcceptClientPro(LPVOID LpP)<br>{<br>    SOCKADDR_IN ClientAdrr;<br>    </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> AddrLen </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">sizeof</span><span style="COLOR: #000000">(SOCKADDR);<br>    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">非阻塞模?/span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000"> (</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">IsConnet)<br>    {<br>        ClientSock </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> accept(SerSocket, (SOCKADDR </span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">)</span><span style="COLOR: #000000">&</span><span style="COLOR: #000000">ClientAdrr, </span><span style="COLOR: #000000">&</span><span style="COLOR: #000000">AddrLen );<br>        </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(INVALID_SOCKET </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> ClientSock)<br>        {<br>            </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> n </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> WSAGetLastError();<br>            </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">没有客户端请?/span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">            </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(WSAEWOULDBLOCK </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> n)    <br>            {<br>                cout</span><span style="COLOR: #000000"><<</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">没有客户端发?</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><<</span><span style="COLOR: #000000">endl;<br>                Sleep(</span><span style="COLOR: #000000">1000</span><span style="COLOR: #000000">);<br>                </span><span style="COLOR: #0000ff">continue</span><span style="COLOR: #000000">;<br>            }</span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"><br>            {<br>                cout</span><span style="COLOR: #000000"><<</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">出现错误!</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><<</span><span style="COLOR: #000000">endl;<br>                Sleep(</span><span style="COLOR: #000000">1000</span><span style="COLOR: #000000">);<br>            }<br>        }</span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"><br>        {<br>            cout</span><span style="COLOR: #000000"><<</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">已连接客L!</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><<</span><span style="COLOR: #000000">endl;<br>            IsConnet </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">true</span><span style="COLOR: #000000">;<br>            </span><span style="COLOR: #0000ff">break</span><span style="COLOR: #000000">;<br>        }<br>    }<br>    </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br>}<br>    <br>    recv函数来说Q在d模式中,如果没有客户端发送数据过来,U程到这里会dQ直到有?br>据发送过来ؓ止。在非阻塞模式中Q没有客L发送数据过来,q回SOCKER_ERRORQ错误代码ؓWSAEWOULDBLOCK?br>如:<br></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">接收数据U程</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">DWORD WINAPI ReceiveDataPro(LPVOID LpP)<br>{<br>    </span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000">(</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">IsConnet);        </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">保证q接后再接受数据</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000">(</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">)<br>    {<br>        </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(IsReadyRecei)        </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">保证~冲区在未处理时不受新来的数据的影响</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">        {<br>            <br>            </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> ReceiLen </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> recv(ClientSock, (</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">)</span><span style="COLOR: #000000">&</span><span style="COLOR: #000000">DataPack, </span><span style="COLOR: #0000ff">sizeof</span><span style="COLOR: #000000">(DataPack), </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">);<br>            </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(SOCKET_ERROR </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> ReceiLen)<br>            {<br>                </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> Err </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> WSAGetLastError();<br>                </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(WSAEWOULDBLOCK </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> Err)<br>                {<br>                    cout</span><span style="COLOR: #000000"><<</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">没有收到数据</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><<</span><span style="COLOR: #000000">endl;<br>                    </span><span style="COLOR: #0000ff">continue</span><span style="COLOR: #000000">;<br>                }<br>                </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (WSAENETDOWN </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> Err </span><span style="COLOR: #000000">||</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">客户端关闭了q接</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">                    WSAETIMEDOUT </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> Err </span><span style="COLOR: #000000">||</span><span style="COLOR: #000000"><br>                    WSAECONNRESET </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> Err )    <br>                {<br>                    cout</span><span style="COLOR: #000000"><<</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">服务器关闭了q接</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><<</span><span style="COLOR: #000000">endl;<br>                    </span><span style="COLOR: #0000ff">break</span><span style="COLOR: #000000">;<br>                }<br>            }<br>            </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> ReceiLen)        </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">客户端关闭了q接</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">            {<br>                cout</span><span style="COLOR: #000000"><<</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">ReceiLen = 0</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><<</span><span style="COLOR: #000000">endl;<br>                </span><span style="COLOR: #0000ff">break</span><span style="COLOR: #000000">;<br>            }<br>            </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(ReceiLen </span><span style="COLOR: #000000">>=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">sizeof</span><span style="COLOR: #000000">(DataPack))        </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">成功接收</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">            {<br>                cout</span><span style="COLOR: #000000"><<</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">已收到数据:</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><<</span><span style="COLOR: #000000">DataPack.buf</span><span style="COLOR: #000000"><<</span><span style="COLOR: #000000">endl;<br>                IsReadyRecei </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">false</span><span style="COLOR: #000000">;<br>                </span><span style="COLOR: #0000ff">break</span><span style="COLOR: #000000">;<br>            }<br>        }<br>    }<br>    </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br>}    <br><br>(</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">)客户?br>    在客L的连接请求线E中Qconnect函数会返回SOCKET_ERRORQ这q不是说明连接失败,具体情况<br>要看它的WSAGetLastError()q回|若它三次q回SOCKET_ERROR的Error代码依次为WSAEWOULDBLOCKQ?br>WSAEINVALQWSAEISCONNQ就说明q接服务器成功,否则p|。但有的时候WSAEINVAL没有出现有WSAEISCONN<br>了,所以我q是以WSAEISCONN接完成的标志Q但要注意其实在三次q回代码中,W一ơ的WSAEWOULDBLOCK<br>之前的connect操作成功了Q如果没出意外服务器p响应了?br>如:<br></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">q接服务器线E?/span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">DWORD WINAPI ConnetServerPro(LPVOID LpP)<br>{<br>    SOCKADDR_IN ServerAddr;<br>    ServerAddr.sin_family </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> AF_INET;<br>    ServerAddr.sin_port </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> htons(</span><span style="COLOR: #000000">1200</span><span style="COLOR: #000000">);<br>    ServerAddr.sin_addr.s_addr </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> inet_addr(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">192.168.1.100</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br>    </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> BlockFlag </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br>    </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> InvalFlag </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br>    </span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000"> (</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">IsConnet)<br>    {<br>        </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> nResu </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> connect(ClientSock, (SOCKADDR </span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">)</span><span style="COLOR: #000000">&</span><span style="COLOR: #000000">ServerAddr, </span><span style="COLOR: #0000ff">sizeof</span><span style="COLOR: #000000">(SOCKADDR));<br>        </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(SOCKET_ERROR </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> nResu)<br>        {<br>            </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> n </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> WSAGetLastError();<br>            <br>            </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(WSAEWOULDBLOCK </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> n )        </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">不能立即完成</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">            {<br>                cout</span><span style="COLOR: #000000"><<</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">q程1!</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><<</span><span style="COLOR: #000000">endl;<br>                BlockFlag</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">;<br>                </span><span style="COLOR: #0000ff">continue</span><span style="COLOR: #000000">;<br>            }<br>            </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(WSAEINVAL </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> n)        </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">监听状?/span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">            {<br>                cout</span><span style="COLOR: #000000"><<</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">q程2!</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><<</span><span style="COLOR: #000000">endl;<br>                InvalFlag</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">;<br>                </span><span style="COLOR: #0000ff">continue</span><span style="COLOR: #000000">;<br>            }<br>            </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(WSAEISCONN </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> n)        </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">q接完成</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">            {<br>                cout</span><span style="COLOR: #000000"><<</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">已连接服务器!</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><<</span><span style="COLOR: #000000">endl;<br>                IsConnet </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">true</span><span style="COLOR: #000000">;<br>                </span><span style="COLOR: #0000ff">break</span><span style="COLOR: #000000">;<br>            }<br>            </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"> <br>            {<br>                cout</span><span style="COLOR: #000000"><<</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">出现其他错误!\n</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><<</span><span style="COLOR: #000000">endl;<br>                Sleep(</span><span style="COLOR: #000000">1000</span><span style="COLOR: #000000">);<br>            }<br>        }<br>    }<br><br>    </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br>}<br><br>    在发送数据线E中Qsend()q回的是发送数据的长度说明发送成功;q回SOCKET_ERRORӞ?br>错误代码为WSAEWOULDBLOCK再重试Q不是WSAEWOULDBLOCKp明有错误。?br>如:<br></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">发送数据线E?/span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">DWORD WINAPI SendDataPro(LPVOID LpP)<br>{<br>    </span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000">(</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">IsConnet);    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">保证已连接服务器</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000">(</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">)<br>    {<br>        </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> len </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> send(ClientSock, (</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">)</span><span style="COLOR: #000000">&</span><span style="COLOR: #000000">DataPack, DataPack.Head.len, </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">);<br>        </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(SOCKET_ERROR </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> len)<br>        {<br>            </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> Error </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> WSAGetLastError();<br>            </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(WSAEWOULDBLOCK </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> Error)<br>                </span><span style="COLOR: #0000ff">continue</span><span style="COLOR: #000000">;<br>        }<br>        </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000">        </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">发送成?/span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">        {<br>            cout</span><span style="COLOR: #000000"><<</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">发送成?</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><<</span><span style="COLOR: #000000">endl;<br>            </span><span style="COLOR: #0000ff">break</span><span style="COLOR: #000000">;<br>        }<br>    }<br><br>    </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br>}</span></div> <img src ="http://m.shnenglu.com/yunboy4/aggbug/91231.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.shnenglu.com/yunboy4/" target="_blank">yunboy</a> 2009-07-26 11:13 <a href="http://m.shnenglu.com/yunboy4/archive/2009/07/26/91231.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>d模式http://m.shnenglu.com/yunboy4/archive/2009/07/26/91230.htmlyunboyyunboySun, 26 Jul 2009 03:09:00 GMThttp://m.shnenglu.com/yunboy4/archive/2009/07/26/91230.htmlhttp://m.shnenglu.com/yunboy4/comments/91230.htmlhttp://m.shnenglu.com/yunboy4/archive/2009/07/26/91230.html#Feedback0http://m.shnenglu.com/yunboy4/comments/commentRss/91230.htmlhttp://m.shnenglu.com/yunboy4/services/trackbacks/91230.html 

1.d模式
    会造成U程d的有下列四种操作Q?br>(
1) 接受q接hQaccept()
(
2) 接受数据Qrecv()Qrecvfrom()
(
3) hq接Qconnect()
(
4) 发送数据:send()Qsendto()
    其中1?最Ҏ发生d?br>    
2、多U程的阻塞模?br>class CServerDlg : public CDialog
{
    SOCKET m_ClientSock;
    SOCKET m_ServerSock;
    HANDLE m_RecvThread;
    HANDLE m_AcceptThread;
    .
    friend  DWORD WINAPI RecvThreadPro(LPVOID LpP);
    friend  DWORD WINAPI AcceptThreadPro(LPVOID LpP);
};
//创徏U程
BOOL CServerDlg::OnInitDialog()
{
    
    
//创徏U程
    DWORD ThreadID;
    m_RecvThread 
= CreateThread(NULL, 0, RecvThreadPro, this, CREATE_SUSPENDED, &ThreadID);
    m_AcceptThread 
= CreateThread(NULL, 0, AcceptThreadPro, this, CREATE_SUSPENDED, &ThreadID);
    
int Count = ResumeThread(m_AcceptThread);
    
}
//接收数据U程
DWORD WINAPI RecvThreadPro(LPVOID LpP)
{
    CServerDlg 
*pServer = (CServerDlg *)LpP;
    ZeroMemory(buf, 
20);
    
int nLen = recv(pServer->m_ClientSock, buf, 200);
    
if(SOCKET_ERROR == nLen) 
        AfxMessageBox(
"Recv Failed!");
    
else
        AfxMessageBox(buf);
    
return 0;
}
//接受客户端请求线E?/span>
DWORD WINAPI AcceptThreadPro(LPVOID LpP)
{
    CServerDlg 
*pServer = (CServerDlg *)LpP;
    
struct sockaddr ClientAddr;
    
int len = sizeof(SOCKADDR_IN);
    pServer
->m_ClientSock = accept(pServer->m_ServerSock, &ClientAddr, &len);
    
if(SOCKET_ERROR == pServer->m_ClientSock)
        AfxMessageBox(
"Accept Failed!");
    
return 0;
}
//l束U程
void CServerDlg::OnClose() 
{
    
// TODO: Add your message handler code here and/or call default
    
//l束AcceptThread
    DWORD ThreadState;
    GetExitCodeThread(m_AcceptThread, 
&ThreadState);
    
if(ThreadState == STILL_ACTIVE)
    {
        
//TerminateThread(m_hThread, 0);
        WaitForSingleObject(m_AcceptThread,0xffffffff); 
        CloseHandle(m_AcceptThread); 
    }
    
//l束RecvThread
    GetExitCodeThread(m_RecvThread, &ThreadState);
    
if(ThreadState == STILL_ACTIVE)
    {
        
//TerminateThread(m_RecvThread, 0);
        WaitForSingleObject(m_RecvThread,0xffffffff); 
        CloseHandle(m_RecvThread); 
    }
    
    
    CDialog::OnClose();
}


yunboy 2009-07-26 11:09 发表评论
]]>
ҹþþӰԺ| ƷþþþӰԺɫ| ޹˾ƷŮ˾þþ| Ʒþþþþþapp | þĻavŮ| þרƷ | ˾Ʒþ| 뾫Ʒþþ| þþþ18| þòþüƵ7| ѾþþƷѾѾ| һþaþþƷvrۺ| 99þùۺϾƷԭ| þþþŮۺ | ޺ݺۺϾþѿ| Ʒ99þò| þ99Ʒ| Ʒþþþþ| Ļɫ͵͵þ| ޹˾Ʒ91þþ | þþݾþþ| ɫۺϾþ| þþܳ| 97þþƷˬ| ޾ƷþþþĻһڣ| ҹƷþþþþž| Ʒһþ| ۲˾þþƷٸAV| ɫۺϾþҹɫƷ| þþþþùƷŮ| ˾þþƷһ| 7777þþùƷ| ĻƷþ| ھƷþþþþþcoent| þþþĻ| þù鶹91| 99ŷƷþþѿ| vavavaþ| ӰȷŮAV³ɫԴþ | ձƬҹþ| þۺϾþۺϾþ|