TCP流式套接字的基本编程

面向连接的客户/服务器程序工作模型

TCP流式套接字的基本编程_第1张图片

服务器端程序

#include < WINSOCK2.H>
#pragma comment( lib, "ws2_32" )
#include < stdio.h>
int main()
{
    printf( " -------------------------/n| 服务器端 |/n|-------------------------/n" );
    //--------------①加载动态链接库Winsock DLL-------------------
    WORD wVersionRequested= MAKEWORD( 2 ,2 );
    WSADATA wsaData;
    if ( WSAStartup( wVersionRequested,& wsaData)!= 0 )
    {
        printf( "WSAStartup Failed/n" );
        printf( "WSAStartup Error=%d/n" , WSAGetLastError());
    }
    else
    {
        printf( "加载Winsock库成功 /n" );
        printf( "调用者希望使用的Winsock版本号=%x/n" , wsaData.wVersion);
        printf( "加载的Winsock库所支持的最高Winsock版本号=%x/n" , wsaData.wHighVersion);
        printf( "wWinsock库的说明字符串=%s/n" ,& wsaData.szDescription[ 0 ]);
        printf( "系统状态或配置信息的说明字符串=%s/n" ,& wsaData.szSystemStatus[ 0 ]);
    }
    //---------------②创建用于监听的流式套接口s---------------
    SOCKET s= socket( AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if ( s== INVALID_SOCKET)
    {
        printf( "|Failed socket/n" );
        printf( "|socket Error=%d/n" , WSAGetLastError());
    }
    else
        printf( "已创建用于监听的套接口,套接口号:[%u]/n" , s);
    //---------------③绑定,使用bind()----------------------
    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.16.1" );   
    if ( bind( s,( sockaddr*)& Sadd, sizeof ( Sadd))== SOCKET_ERROR)
    {
        printf( "Failed bind()/n" );
        printf( "bind Error=%d/n" , WSAGetLastError());
    }
    else
    {
        printf( "绑定成功/n" );
        printf( "本地IP地址:[%s],本地端口号:[%u]/n" , inet_ntoa( Sadd.sin_addr), ntohs( Sadd.sin_port));
    }
    //---------------④监听状态-------------
    if ( listen( s, 2 )== SOCKET_ERROR)
    {
        printf( "Failed listen()/n" );
        printf( "listen Error=%d/n" , WSAGetLastError());
    }
    //----------------⑤循环接受客户的连接请求---------------------------
    struct sockaddr_in Cadd;
    int caddLen= sizeof ( Cadd);
    SOCKET c;
    while ( TRUE )
    {
        printf( "|----------------------------/n" );
        printf( "|进入监听状态...../n|--------------------------------|/n" );
        c= accept( s,( sockaddr*)& Cadd,& caddLen);
        if ( c== INVALID_SOCKET)
        {
            printf( "|Failed accept()/n" );
            printf( "|accept Error=%d/n" , WSAGetLastError());
        }
        else
            printf( "|可以在套接口[%u]上发送接收数据了!/n" , c);
        //#########################开始发送、接收###################### 注意都要在新套接口c上进行
        //#########################结束发送、接收######################
        closesocket( c);
        printf( "|与主机IP地址是:[%s]/n|端口号是:[%u]的连接完毕/n" , inet_ntoa( Cadd.sin_addr), ntohs( Cadd.sin_port));
        char xx;
        printf( "|-------------------------------------/n需要退出吗?(Y/N)" );
        scanf( "%c" ,& xx);
        if ( xx== 'Y' || xx== 'y' )
        {
            break ;
        }
    }
    closesocket( s);
    WSACleanup();
    return 0 ;
}

客户端程序

#include < WINSOCK2.H>
#pragma comment( lib, "WS2_32" )
#include < stdio.h>

int main()
{
    printf( "------------------------/n| 客户端 |/n|---------------------------------------/n" );
    //------①加载动态链接库winsock DLL-----------
    printf( "|加载等待中.... " );
    WSADATA wsaData;
    WORD wVersionRequested= MAKEWORD( 2 ,2 );
    if ( WSAStartup( wVersionRequested,& wsaData)!= 0 )
    {
        printf( "|WSAStartup Failed/n" );
        printf( "|WSAStartup Error=%d/n" , WSAGetLastError());
    }
    else
    {
        printf( "加载Winsock 库成功 |/n" );
    }
    printf( "|---------------------------------------/n" );
    //-------②创建用于监听的流式套接口s,使用socket()-----------------
    SOCKET s= socket( AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if ( s== INVALID_SOCKET)
    {
        printf( "|Failed socket/n" );
        printf( "|socket Error=%d/n" , WSAGetLastError());
    }
    else
        printf( "|已创建用于监听的套接口,套接口号:[%u]/n" , s);
    printf( "|---------------------------------------/n" );
    //------③本地地址bind(可以不做这部分,如果不绑定,系统将自动分配)--------
    /*struct sockaddr_in Cadd;
    Cadd.sin_family=AF_INET;
    Cadd.sin_port=htons(4444);
    Cadd.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
    if (bind(s,(sockaddr*)&Cadd,sizeof(Cadd))==SOCKET_ERROR)
    {
        printf("|Failed bind()/n");
    }*/

    //-------填写要连接的服务器地址信息---------
    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.16.1" );
    //--------④将套接口s与远程主机相连--------------
    if ( connect( s,( sockaddr*)& Sadd, sizeof ( Sadd))== INVALID_SOCKET)
    {
        printf( "|Failed connect()/n" );
        printf( "|connect Error=%d/n" , WSAGetLastError());
    }
    else
    {
        //####################开始发接数据########################
        printf( "|连接成功,可以开始发送接收数据了!/n" );
        printf( "|服务器IP地址:[%s]/n 端口号:[%u]/n" , inet_ntoa( Sadd.sin_addr), ntohs( Sadd.sin_port));
        //####################结束发接数据########################
    }
    //--------------⑤关闭套接字s,终止对动态链接库的访问----------
    closesocket( s);
    printf( "|---------------------------------------/n" );
    printf( "|连接完毕/n" );
    WSACleanup();
    return 0 ;
}

TCP流式套接字的基本编程_第2张图片

你可能感兴趣的:(编程,tcp,socket,Stream,struct,服务器)