很好很好的select服务器程序,可直接运行,新手福利测试修改

本文介绍了一个使用Winsock实现的简单非阻塞多线程服务器端程序。该程序通过加载Winsock库、创建套接字、绑定地址、监听连接请求等步骤完成服务器搭建,并采用select函数来处理多个客户端连接。


#define  FD_SETSIZE 500
#include "stdafx.h"
#include <iostream>
#include <stdlib.h>
#include "winsock2.h"
#pragma comment (lib,"ws2_32.lib")
 int  main()
 {
     printf( "服务器端程序....\n" );
     //------①加载----------
    WSADATA wsaData;
     if  ( WSAStartup( MAKEWORD( 2 ,2 ),& wsaData)!= 0 )
     {
         printf( "WSAStartup Failed,Error=【%d】\n" , WSAGetLastError());
         return  1 ;
     }
     else
         printf( "①加载成功\n" );
     //-------②创建流式套接字------------
    SOCKET s= socket( AF_INET, SOCK_STREAM, 0 );
     if  ( s== INVALID_SOCKET)
     {
         printf( "socket() Failed,Error=【%d】\n" , WSAGetLastError());
         return  1 ;
     }
     else
         printf( "②已创建监听套接口:【%d】\n" , s);
     //将套接口s置于”非阻塞模式“
    u_long u1= 1 ;
     ioctlsocket( s, FIONBIO,( u_long*)& u1);
     //-----------③绑定本地地址---------------------
    struct  sockaddr_in Sadd;
     Sadd.sin_family= AF_INET;
     Sadd.sin_port= htons( 5555 );
     Sadd.sin_addr.S_un.S_addr= inet_addr( "192.168.31.1" );
     if  ( bind( s,( sockaddr*)& Sadd, sizeof ( Sadd))== SOCKET_ERROR)
     {
         printf( "bind() Failed,Error=【%d】\n" , WSAGetLastError());
         return  1 ;
     }
     else
         printf( "③绑定成功,本地IP地址:【%s】,端口号:【%d】\n" , inet_ntoa( Sadd.sin_addr), ntohs( Sadd.sin_port));
     //--------------④进入监听状态-----------------
    if  ( listen( s, 3 )== SOCKET_ERROR)
     {
         printf( "listen Failed,Error=【%d】\n" , WSAGetLastError());
         return  1 ;
     }
     else
         printf( "④进入监听状态\n" );
     //--------------⑤select-------------------
    //准备工作
    int  x= 1 ;
     timeval tv;
     tv.tv_sec= 20 ;
     tv.tv_usec= 0 ;
     fd_set socket_jh01;
     FD_ZERO(& socket_jh01);
     FD_SET( s,& socket_jh01);
     fd_set socket_jh02;
     FD_ZERO(& socket_jh02);
     while  ( TRUE )
     {
         socket_jh02= socket_jh01;
         int  sock_sum= select( 0 ,& socket_jh02, NULL , NULL ,& tv);
         //------情况一  成功
        if  ( sock_sum> 0 )
         {
             for  ( int  i= 0 ;i<( int ) socket_jh02.fd_count; i++)
             {
                 if  ( socket_jh02.fd_array[ i]== s)
                 {
                     if  ( socket_jh01.fd_count< FD_SETSIZE)
                     {
                         sockaddr_in Cadd;
                         int  Cadd_len= sizeof ( Cadd);
                         SOCKET sNew= accept( s,( sockaddr*)& Cadd,& Cadd_len);
                         FD_SET( sNew,& socket_jh01);
                         printf( "接受一个客户端连接,对方地址:【%s】,端口号:【%d】\n" , inet_ntoa( Cadd.sin_addr), ntohs( Cadd.sin_port));
                         printf( "分配给该客户端的套接口为:%d\n\n" , sNew);
                     }
                     else
                     {
                         printf( "连接数量太多\n" );
                         continue ;
                     }
                 }
                 else
                 {
                     char  cbuf[ 256 ];
                     memset( cbuf, 0 ,256 );
                     int  cRecv;
                     cRecv= recv( socket_jh02.fd_array[ i], cbuf, 256 ,0 );
                     if  ( cRecv== SOCKET_ERROR)
                     {
                         printf( "可能客户端%d非法关闭!!" , socket_jh02.fd_array[ i]);
                         printf( "或者调用recv() Failed,Error=【%d】\n" , WSAGetLastError());
                         closesocket( socket_jh02.fd_array[ i]);
                         FD_CLR( socket_jh02.fd_array[ i],& socket_jh01);
                     }
                     else  if  ( cRecv> 0 )
                     {
                         printf( "接收到来至【%d】的数据:%s\n" , socket_jh02.fd_array[ i], cbuf);
                         int  isend;
                         char  Sbuf[]= "Hello client!I am server" ;
                         isend= send( socket_jh02.fd_array[ i], Sbuf, sizeof ( Sbuf), 0 );
                         if  ( isend== SOCKET_ERROR)
                         {
                             printf( "send() Failed,Error=【%d】\n" , WSAGetLastError());
                             break ;
                         }
                         else  if  ( isend<= 0 )
                         {
                             printf( "消息发送失败!!\n" );
                             break ;
                         }
                         else
                             printf( "给客户【%d】信息已发送,信息长度%d字节\n\n" , socket_jh02.fd_array[ i], isend);
                     }
                     else
                     {
                         printf( "客户端【%d】不再发送数据,正常关闭连接,为客户端连接创建的套接口将关闭!!\n" , socket_jh02.fd_array[ i]);
                         closesocket( socket_jh02.fd_array[ i]);
                         FD_CLR( socket_jh02.fd_array[ i],& socket_jh01);
                     }
                 }
             } //end for
         } //end sock_sum
         //------------情况二  超时
        else  if  ( sock_sum== 0 )
         {
             printf( "第【%d】次超时\n" , x);
             if  ( x< 3 )
             {
                 x++;
                 continue ;
             }
             else
             {
                 printf( "超过等待限制,退出程序\n" );
                 break ;
             }
         }
         //--------------情况三  失败
        else
         {
             printf( "select() Failed,Error=【%d】\n" , WSAGetLastError());
             break ;
         }
     } //while end
     closesocket( s);
     printf( "退出" );
     WSACleanup();
     return  0 ;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值