<i id='qr2qv'></i>

      <fieldset id='qr2qv'></fieldset>
      <ins id='qr2qv'></ins><span id='qr2qv'></span>
    1. <tr id='qr2qv'><strong id='qr2qv'></strong><small id='qr2qv'></small><button id='qr2qv'></button><li id='qr2qv'><noscript id='qr2qv'><big id='qr2qv'></big><dt id='qr2qv'></dt></noscript></li></tr><ol id='qr2qv'><table id='qr2qv'><blockquote id='qr2qv'><tbody id='qr2qv'></tbody></blockquote></table></ol><u id='qr2qv'></u><kbd id='qr2qv'><kbd id='qr2qv'></kbd></kbd>
      1. <acronym id='qr2qv'><em id='qr2qv'></em><td id='qr2qv'><div id='qr2qv'></div></td></acronym><address id='qr2qv'><big id='qr2qv'><big id='qr2qv'></big><legend id='qr2qv'></legend></big></address>

      2. <dl id='qr2qv'></dl>
        <i id='qr2qv'><div id='qr2qv'><ins id='qr2qv'></ins></div></i>

          <code id='qr2qv'><strong id='qr2qv'></strong></code>

          Linux下使用TCP通讯时遇到的问题

          • 时间:
          • 浏览:2
          • 来源:124软件资讯网

            在这里总结一下这linux用TCP通讯需要注重的几个问题  ,都是前一阵子事情中遇到的问题  。

            问题1. 发送和吸收数据时的不完整问题

            以吸收为例 ,当对端发送1000个字节的数据时  ,本端举行吸收  ,会泛起挪用recv返回500而且errno==EAGAIN的情形(测试中发现这种情形很是严重)  ,这个错误表现当前装备忙 ,稍后再试  。理想化的解决措施是这样的:

            使用select或者epoll机制  ,当有数据到来时  ,select或epoll会通知  ,此时一直吸收直到recv返回0表现所有数据都吸收完  。历程中当errno==EAGAIN则暂停吸收 ,并将已经吸收的数据缓存起来  。当装备再次可读时select或者epoll会再次通知  ,在缓存数据的后面继续吸收  ,云云重复n次直到recv返回值为0  。

            可是这种要领需要把已经吸收的部门数据举行缓存 ,实现起来很是繁琐  ,我举行了如下的简朴实现  ,是我封装的epoll中的部门代码:

            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;

            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;
            }


            问题2. 洁净的关闭socket  ,应该使用如下要领来关闭你不使用的socket  ,不要仅仅挪用close():

            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);


            close (s);
            }