免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 6580 | 回复: 11
打印 上一主题 下一主题

HELP,多线程通过同一个socket发送数据到服务端,socket底动会不会同步呢? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-05-09 13:06 |只看该作者 |倒序浏览
最近写了一个网络通过框架,在运行过程中,在同一时刻,多个线程通过同一个socket发送数据到服务端发送数据到服务器,程序在VMWARE上一切正常,但到实际机器上偶尔出现收到的数据内容错误的情况(在通信量比较大的时候,多个线程通过该连接每秒发送几千个消息包,操作系统:REHL5)。请问一下,同多个线程通过同一个socket发送数据,操作系统底层会同步每个发送操作吗?

论坛徽章:
324
射手座
日期:2013-08-23 12:04:38射手座
日期:2013-08-23 16:18:12未羊
日期:2013-08-30 14:33:15水瓶座
日期:2013-09-02 16:44:31摩羯座
日期:2013-09-25 09:33:52双子座
日期:2013-09-26 12:21:10金牛座
日期:2013-10-14 09:08:49申猴
日期:2013-10-16 13:09:43子鼠
日期:2013-10-17 23:23:19射手座
日期:2013-10-18 13:00:27金牛座
日期:2013-10-18 15:47:57午马
日期:2013-10-18 21:43:38
2 [报告]
发表于 2009-05-09 13:28 |只看该作者
这么做没法保证数据发送的先后,考虑到阻塞的因素,数据会乱套的。
socket通信没有你这样的模型,这种创新还是免了

论坛徽章:
5
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:53:172015亚冠之水原三星
日期:2015-06-02 16:34:202015年亚冠纪念徽章
日期:2015-10-19 18:13:37程序设计版块每日发帖之星
日期:2015-11-08 06:20:00
3 [报告]
发表于 2009-05-09 13:46 |只看该作者
只在UDP中这么用过,顺序无所谓

论坛徽章:
0
4 [报告]
发表于 2009-05-09 13:59 |只看该作者
每个连接都有块发送缓冲区,send系统调用就是将用户态的数据拷贝到内核态内存中,然后send返回,多个线程对同一个连接进行send,就出现多个包交叉放到内核缓冲区中。

论坛徽章:
0
5 [报告]
发表于 2009-05-09 13:59 |只看该作者
顺序到无所谓,每个消息都包括消息头和消息体,消息头中有消息的长度信息,所以顺序到应该不需要考虑。

论坛徽章:
0
6 [报告]
发表于 2009-05-09 14:07 |只看该作者
因为按当初的设计,至少要支持5000个连接,如果每个连接一个pthread_mutex_t,这样至少就有5000个锁,太多的加锁和解锁,效率应该很受影响。
  由于要支持的连接数过大,所以也不好让每个连接都有一个私家发送线程.所以导致现在可能存在多个线程同时通过一个连接发送数据的情况出现

论坛徽章:
0
7 [报告]
发表于 2009-05-09 14:14 |只看该作者
原帖由 xuyun11141 于 2009-5-9 14:07 发表
因为按当初的设计,至少要支持5000个连接,如果每个连接一个pthread_mutex_t,这样至少就有5000个锁,太多的加锁和解锁,效率应该很受影响。
  由于要支持的连接数过大,所以也不好让每个连接都有一个私家发送 ...

EPOLL
异步处理,单线程即可。

论坛徽章:
0
8 [报告]
发表于 2009-05-09 14:20 |只看该作者
to cugb_cat :
在接收的时,用的是epoll的ET,一个线程专门epoll_wait,然后把有读通过的socket分给线程池的线程,所以读方面应该不会有问题。但写的时候就不知道怎么用epoll管理了,因为使用了消息队列,如果每次检测一个SOCKET可读的时候再去消息队列中取将通过该连接发送的消息,这样每次发送发轮询消息队列,整个通信框架就一个用于存在等待发送的消息队列,如果通信量大的情况下,可能某时刻,消息队列中的太多的等待发送的消息。

通过对epoll管理socket读的通过方面提一个建议吗?谢谢

论坛徽章:
0
9 [报告]
发表于 2009-05-09 14:22 |只看该作者
发送函数代码如下:
int Socket::Send(int nHandle,const char *pstrDataBuf,unsigned int &nLen,int nFlags /* = 0 */)
{
    if ((nHandle < 0) || (NULL == pstrDataBuf))
    {
        return -1;
    }
   
    int nResult = 0;
    int nRemainSize = (int)nLen;
    int nSentSize = 0;
    const char *pstrTmp = pstrDataBuf;
    fd_set writefds;
    time_t tStartTime = time(NULL);
    int nTimeout = 3;
    struct timeval tv = {0};
   
    do
    {
        if (time(NULL) > tStartTime + nTimeout)
        {
            return -1;
        }

        FD_ZERO(&writefds);
        FD_SET(nHandle, &writefds);

        tv.tv_usec = 0;
        tv.tv_sec = 1;
        if ((nResult = select(nHandle + 1, NULL, &writefds,NULL,&tv)) == 0)
        {
            return -1;
        }
        else if ( nResult < 0 )
        {
            if ((errno == EAGAIN) || (errno == EWOULDBLOCK) || (errno == EINTR))
            {
                continue;
            }
    return errno;
        }

        nSentSize = send(nHandle,pstrTmp,nRemainSize,nFlags);

        //发送失败
        if (nSentSize < 0)
        {
            if ((errno == EAGAIN) || (errno == EWOULDBLOCK) || (errno == EINTR))
            {
                continue;
            }
            else
            {
                nLen -= nRemainSize;
                return errno;
            }
        }

        //发送成功
        pstrTmp += nSentSize;
        nRemainSize -= nSentSize;
    }while(nRemainSize > 0);

      //fprintf(stderr,"send size = %d",nSentSize);
    return 0;
}

论坛徽章:
0
10 [报告]
发表于 2009-05-09 14:24 |只看该作者
to  cugb_cat   :
能否提示一下,EPOLL,异步处理,单线程处理发送的情况呢?谢谢
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP