ºìÁªLinuxÃÅ»§
Linux°ïÖú

С½áÒ»ÏÂLinuxÏÂʹÓÃTCPͨѶʱÓöµ½µÄÎÊÌâ

·¢²¼Ê±¼ä:2008-05-17 01:20:40À´Ô´:ºìÁª×÷Õß:Dssiuet
ÔÚÕâÀï×ܽáÒ»ÏÂÕâlinuxÓÃTCPͨѶÐèҪעÒâµÄ¼¸¸öÎÊÌ⣬¶¼ÊÇÇ°Ò»Õó×Ó¹¤×÷ÖÐÓöµ½µÄÎÊÌâ¡£

ÎÊÌâ1. ·¢ËͺͽÓÊÕÊý¾ÝʱµÄ²»ÍêÕûÎÊÌâ

ÒÔ½ÓÊÕΪÀý£¬µ±¶Ô¶Ë·¢ËÍ1000¸ö×Ö½ÚµÄÊý¾Ýʱ£¬±¾¶Ë½øÐнÓÊÕ£¬»á³öÏÖµ÷ÓÃrecv·µ»Ø500²¢ÇÒerrno==EAGAINµÄÇé¿ö£¨²âÊÔÖз¢ÏÖÕâÖÖÇé¿ö·Ç³£ÑÏÖØ£©£¬Õâ¸ö´íÎó±íʾµ±Ç°É豸棬ÉÔºóÔÙÊÔ¡£ÀíÏ뻯µÄ½â¾ö°ì·¨ÊÇÕâÑùµÄ£º

ʹÓÃselect»òÕßepoll»úÖÆ£¬µ±ÓÐÊý¾Ýµ½À´Ê±£¬select»òepoll»á֪ͨ£¬´Ëʱһֱ½ÓÊÕÖ±µ½recv·µ»Ø0±íʾËùÓÐÊý¾Ý¶¼½ÓÊÕÍê¡£¹ý³ÌÖе±errno==EAGAINÔòÔÝÍ£½ÓÊÕ£¬²¢½«ÒѾ­½ÓÊÕµÄÊý¾Ý»º´æÆðÀ´¡£µ±É豸ÔٴοɶÁʱselect»òÕßepoll»áÔÙ´Î֪ͨ£¬ÔÚ»º´æÊý¾ÝµÄºóÃæ¼ÌÐø½ÓÊÕ£¬Èç´Ë·´¸´n´ÎÖ±µ½recv·µ»ØֵΪ0¡£

µ«ÊÇÕâÖÖ·½·¨ÐèÒª°ÑÒѾ­½ÓÊյIJ¿·ÖÊý¾Ý½øÐлº´æ£¬ÊµÏÖÆðÀ´·Ç³£·±Ëö£¬ÎÒ½øÐÐÁËÈçϵļòµ¥ÊµÏÖ£¬ÊÇÎÒ·â×°µÄepollÖеIJ¿·Ö´úÂ룺[code]int
mo_epoll_recv (int s, void* buf, int buf_size, int err)
{
int recved_len = 0;
int total_recv_len = 0;
int count = 0;

if (buf == NULL || buf_size <= 0)
{
return -1;
}

MO_DEBUG ("to recv some data!\n");

do
{
//MO_DEBUG ("call recv, total_recv_len=%d recv_len=%d\n", total_recv_len, buf_size-total_recv_len);
recved_len = recv (s, buf+total_recv_len, buf_size-total_recv_len, err);

//MO_DEBUG ("called recv, recved_len=%d\n, errno=%d:EAGAIN=%d:%s\n", recved_len, errno, EAGAIN, strerror (errno));

if (recved_len < 0 && errno != EAGAIN)
{
MO_ERROR ("some error when recv erron: %d, %s", errno, strerror (errno));
break;
}
else if (recved_len < 0 && errno == EAGAIN)
{
recved_len = 1;
/* 10s timeout */
if (++count > 200)
{
break;
}
usleep (1000*50);
continue;
}
total_recv_len += recved_len;
if (total_recv_len >= buf_size)
{
recved_len = 0;
//MO_DEBUG ("recv %d bytes!!!!!", total_recv_len);
break;
}
usleep (1000*50);
}while(recved_len > 0);
MO_DEBUG ("recv some data over %d bytes!\n", total_recv_len);

if (recved_len == -1)
return -1;

return total_recv_len;
}
int
mo_epoll_send (int s, const void* buf, int buf_size, int err)
{
int sended_len = 0;
int total_send_len = 0;

if (buf == NULL || buf_size <= 0)
{
return -1;
}
MO_DEBUG ("to send some data!\n");

do
{
sended_len = send (s, (buf+total_send_len), buf_size-total_send_len, err);
if (sended_len == -1 && errno != EAGAIN)
{
break;
}
else if (sended_len == -1 && errno == EAGAIN)
{
sended_len = 1;
continue;
}
total_send_len += sended_len;
if (total_send_len >= buf_size)
{
sended_len = 0;
//MO_DEBUG ("send %d bytes!!!!!", total_send_len);
break;
}
}while(sended_len > 0);
MO_DEBUG ("send some data over %d bytes!\n", total_send_len);

if (sended_len == -1)
return -1;

return total_send_len;
}[/code]ÎÊÌâ2. ¸É¾»µÄ¹Ø±Õsocket£¬Ó¦¸ÃʹÓÃÈçÏ·½·¨À´¹Ø±ÕÄ㲻ʹÓõÄsocket£¬²»Òª½ö½öµ÷ÓÃclose()£º[code]void
cleanclose (int s)
{
int i = 0;
char buf[100];
/* ¹Ø±ÕдÈë */
shutdown (s, SHUT_WR);
/* ½ÓÊÕËùÓÐÊý¾Ý */
do
{
i = recv (s, buf, 100, 0);
}while (i > 0);
/* ¹Ø±Õ¶ÁÈ¡ */
shutdown (s, SHUT_RD);

/* ¹Ø±Õsocket */
close (s);
}[/code]
ÎÄÕÂÆÀÂÛ

¹²ÓÐ 0 ÌõÆÀÂÛ