| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1068 人关注过本帖
标题:(分享)winsock 编程基础 之 阻塞 I/O 模型
只看楼主 加入收藏
funyh250
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:26
帖 子:290
专家分:1573
注 册:2013-12-25
结帖率:100%
收藏
已结贴  问题点数:100 回复次数:10 
(分享)winsock 编程基础 之 阻塞 I/O 模型
程序代码:
    WSAData wsaDate;                                    //声明一个WSADate结构体(包含了Winsock库的版本信息)变量 
    int nRet=WSAStartup(MAKEWORD(2,2),&wsaDate);          //初始化该结构体(协商版本) 若返回0则成功
    //if(nRet!=0)
    //错误处理
    sockaddr_in saServer;                                //声明一个地址结构体 sockaddr是系统自己使用的 
    saServer.sin_family=AF_INET;                       //必须是AF_INET
    saServer.sin_port=htons(10000);                   //必须转换成网络字节序 htonl/htons (host to net long/ short)
    saServer.sin_addr.s_addr=htonl(INADDR_ANY);        //接收任意IP的数据 (通配地址)               //数字是short 字符long
    SOCKET sasocket;                                  //声明一个套接字句柄变量
    sasocket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);//使用UDP时的参数SOCK_DGRAM IPPROTO_UDP

    bind(sasocket,(sockaddr*)&saServer,sizeof(saServer));//绑定成功返回0  否则SOCK_ERROR
    listen(sasocket,1);//backlog表示可以接受的客服请求的最大数量 监听成功返回0  SOCK_ERROR

    sockaddr_in saClient;                             //客服端的地址结构体
    int nsaClient=sizeof(sockaddr);                     //客服端地址信息的大小
    SOCKET hClientsocket=accept(sasocket,(sockaddr*)&saClient,&nsaClient);//接收客服端的连接请求
                                                       //返回的套接字将用于与这个客服的连接  sasocket可以继续接受其他客服请求
                                                       //如果请求队列为空 那么将被阻塞 失败返回INVALID_SOCKET

    const int buff_len=1024;
    char recvbuff[buff_len+1];
    nRet=recv(hClientsocket,recvbuff,buff_len,0);//返回接收数据的实际大小 失败返回SOCKET_ERROR flags参数有MSG_PEEK MSG_OOB 或一起使用
    //如果系统能接收的最大数据量为len 那么recv将返回len 但不能超过buff_len 
    //如果系统缓存区满了 那么调用recv的线程将被阻塞(停止运行) ,直到系统可以接收数据

    //************确保接收(发送)全部数据********************************************************
    int nbuff_len=520;//假设要接受的数据大小为520                                   
    int nn=0;                                                                       
    while(nbuff_len>0)                                                              
    {                                                                               
        int ret=recv(hClientsocket,&recvbuff[nn],nbuff_len,0);                      
                                       //nn在增加  nbuff_len在递减                  
        if(ret=SOCKET_ERROR)       //发送失败 就这一种情况                          
        {                                                                           
            //错误处理                                                              
        }                                                                        
        else                                                                       
            if(ret==0)                                                            
            {                                                                       
                //连接被发送方关闭,错误处理                                          
            }                                                                       
            nn+=ret;                                                                
            nbuff_len-=ret;                                                        
    }                                                                              
    //**********************************************************************************************

    int nSend=send(hClientsocket,recvbuff,nRet,0);//把接收到的实际数据的大小发送出去 flags参数有MSG_DONTROUTE MSG_OOB 或一起使用
    //nRet不能超过系统接收的最大长度            SOCKET_ERROR
    //

    shutdown(hClientsocket,SD_SEND);//SOCKET_ERROR  如果是UDP 此操作不需要 因为每次发送(接收)的都是完整的数据报
    //shutdown之后还在接收数据
    //do
    //{              数据流还在流向接收端直到全部到达
    //ret=recv(hClientsocket,&recvbuff[nn],nbuff_len,0);
    //}while(ret!=0)
    //如果ret==0了
    closesocket(hClientsocket);//SOCKET_ERROR
    WSACleanup();//清除关于winsock的一切资源


学习笔记分享下
搜索更多相关主题的帖子: 结构体 模型 网络 信息 
2014-06-22 18:01
funyh250
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:26
帖 子:290
专家分:1573
注 册:2013-12-25
收藏
得分:0 
怎么发了两个

学习是大事   吃喝拉撒睡是小事   其他的那都不是事
2014-06-22 18:05
azzbcc
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:江西财经大学
等 级:贵宾
威 望:81
帖 子:3293
专家分:12919
注 册:2012-11-4
收藏
得分:20 


[fly]存在即是合理[/fly]
2014-06-22 18:10
lscalin
Rank: 6Rank: 6
来 自:周总理故乡
等 级:侠之大者
威 望:1
帖 子:91
专家分:405
注 册:2010-5-10
收藏
得分:20 
留个脚印,说不定要用到,哈哈

灵感不是曹操,说来就来。
2014-06-22 21:08
yuccn
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:何方
等 级:版主
威 望:167
帖 子:6814
专家分:42393
注 册:2010-12-16
收藏
得分:20 

我行我乐
公众号:逻辑客栈
我的博客:
https://blog.yuccn. net
2014-06-23 13:54
宇智波鼬123
Rank: 2
来 自:天津
等 级:论坛游民
威 望:4
帖 子:42
专家分:46
注 册:2014-6-21
收藏
得分:20 
也许以后会有用的
2014-06-23 16:41
hubinyes
Rank: 7Rank: 7Rank: 7
等 级:贵宾
威 望:11
帖 子:104
专家分:557
注 册:2014-2-4
收藏
得分:20 
阻塞。。。
2014-06-23 20:12
邵帅
Rank: 7Rank: 7Rank: 7
等 级:贵宾
威 望:20
帖 子:174
专家分:505
注 册:2012-8-27
收藏
得分:0 
回复 楼主 funyh250
请教一个问题,如果使用socket通讯。
A 与B1 B2 B3 B4 B5……BN进行通讯
1.A为服务器,B1……为客户端
2.A为客户端,B1……为服务器

1,2哪一个更好,是否存在一些选择的条件?
望不吝赐教。

Figure out what you like. Try to become the best in the world of it.
2014-06-28 16:17
funyh250
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:26
帖 子:290
专家分:1573
注 册:2013-12-25
收藏
得分:0 
回复 8 楼 邵帅
大多数情况下都是1

学习是大事   吃喝拉撒睡是小事   其他的那都不是事
2014-06-28 19:02
邵帅
Rank: 7Rank: 7Rank: 7
等 级:贵宾
威 望:20
帖 子:174
专家分:505
注 册:2012-8-27
收藏
得分:0 
回复 9 楼 funyh250
我想简单的分析一下,不知说的是否正确:
如果用1,那么系统的建立比较简单,对于客户端B1……BN,只需知道服务器的IP和端口即可,服务器A通过阻塞模型、就绪通告模型或异步IO模型来处理多客户端通讯。
如果用2,客户端A需要知道B1……BN的IP和端口(这一点比较麻烦),服务器的通讯程序比较简单,因为客户端只有一个。
2的性能应该比1要好,因为2是多个端口与多个端口的通讯,而1是1个端口与多个端口的通讯。(假设IO模型选择一致)

望不吝赐教!

Figure out what you like. Try to become the best in the world of it.
2014-07-01 16:00
快速回复:(分享)winsock 编程基础 之 阻塞 I/O 模型
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.016530 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved