Windows网络编程之(一)Socket阻塞模式(TCP和UDP)

TCP通信

Server

#include 
#include 

static const int PORT = 7777;
static const int BUFFER_LENGTH = 128 ;

bool InitWSA() ;

int main()
{
    if(!InitWSA())
    {
        return -1 ;
    }

    SOCKET sockSrv = socket (AF_INET, SOCK_STREAM, 0) ;

    SOCKADDR_IN addrSrv ;
    addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_LOOPBACK) ;
    addrSrv.sin_family = AF_INET ;
    addrSrv.sin_port = htons(PORT) ;

    bind (sockSrv, (SOCKADDR *)&addrSrv, sizeof(SOCKADDR)) ;

    listen (sockSrv, 1) ;

    SOCKADDR_IN addrClient ;
    int len = sizeof (addrClient) ;

    while (true)
    {
        SOCKET sockConn = accept(sockSrv, (SOCKADDR *)&addrClient, &len) ;

        char sendBuf[BUFFER_LENGTH] ;
        sprintf(sendBuf, "Hello, %s, This is Server.", inet_ntoa(addrClient.sin_addr)) ;

        send(sockConn, sendBuf, strlen(sendBuf) + 1, 0 ) ;

        char recvBuf[BUFFER_LENGTH] ;
        recv (sockConn, recvBuf, BUFFER_LENGTH, 0) ;
        printf("%s", recvBuf) ;
        closesocket(sockConn) ;
    }

    closesocket(sockSrv) ;
    WSACleanup () ;

    return 0 ;
}

bool InitWSA()
{
    WORD wVersionRequested;
    WSADATA wsaData;
    int err;

    wVersionRequested = MAKEWORD( 1, 1 );
    err = WSAStartup( wVersionRequested, &wsaData );
    if ( err != 0 ) 
    {                                 
        return false ;
    }
    if ( LOBYTE( wsaData.wVersion ) != 1 ||
        HIBYTE( wsaData.wVersion ) != 1 ) 
    {
        WSACleanup();
        return false ; 
    }
    return true ;
}

TCP Server流程

  • 创建Socket对象
  • bind地址
  • listen 监听
  • accept 接受连接
  • send,recv 发送、接收数据
  • 关闭Socket对象

Client

#include 
#include 

static const int PORT = 7777;
static const int BUFFER_LENGTH = 128 ;

bool InitWSA() ;

int main()
{
    if(!InitWSA())
    {
        return -1 ;
    }

    SOCKET sockClient = socket (AF_INET, SOCK_STREAM, 0) ;

    SOCKADDR_IN addrSrv ;
    addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_LOOPBACK) ;
    addrSrv.sin_family = AF_INET ;
    addrSrv.sin_port = htons(PORT) ;

    connect (sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));

    char recvBuf[BUFFER_LENGTH] ;
    recv(sockClient, recvBuf, BUFFER_LENGTH, 0) ;
    printf ("%s\n", recvBuf) ;
    send (sockClient, "Hello, This is Client\n", strlen("Hello, This is Client\n") + 1, 0) ;

    closesocket (sockClient) ;
    WSACleanup () ;

    return 0 ;
}

bool InitWSA()
{
    WORD wVersionRequested;
    WSADATA wsaData;
    int err;

    wVersionRequested = MAKEWORD( 1, 1 );
    err = WSAStartup( wVersionRequested, &wsaData );
    if ( err != 0 ) 
    {                                 
        return false ;
    }
    if ( LOBYTE( wsaData.wVersion ) != 1 ||
        HIBYTE( wsaData.wVersion ) != 1 ) 
    {
        WSACleanup();
        return false ; 
    }
    return true ;
}

TCP Client流程

  • 创建Socket对象
  • connect 连接
  • send,recv 发送、接收数据
  • 关闭Socket对象

UDP通信

Server

#include 
#include 


static const int PORT = 7777;
static const int BUFFER_LENGTH = 128 ;

bool InitWSA() ;

int main()
{
    if(!InitWSA())
    {
        return -1 ;
    }

    SOCKET sockSrv = socket(AF_INET, SOCK_DGRAM, 0) ;

    SOCKADDR_IN addrSrv ;
    addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_LOOPBACK);
    addrSrv.sin_family = AF_INET ;
    addrSrv.sin_port = htons (PORT) ;

    bind(sockSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR)) ;

    SOCKADDR_IN addrClient ;
    int len = sizeof (SOCKADDR) ;
    char recvBuf[BUFFER_LENGTH] ;

    recvfrom (sockSrv, recvBuf, BUFFER_LENGTH, 0, (SOCKADDR *)&addrClient, &len) ;
    printf("%s", recvBuf) ;
    closesocket(sockSrv) ;

    WSACleanup() ;

    return 0 ;
}

bool InitWSA()
{
    WORD wVersionRequested;
    WSADATA wsaData;
    int err;

    wVersionRequested = MAKEWORD( 1, 1 );
    err = WSAStartup( wVersionRequested, &wsaData );
    if ( err != 0 ) 
    {                                 
        return false ;
    }
    if ( LOBYTE( wsaData.wVersion ) != 1 ||
        HIBYTE( wsaData.wVersion ) != 1 ) 
    {
        WSACleanup();
        return false ; 
    }
    return true ;
}

UDP Server流程

  • 创建Socket对象
  • bind地址
  • listen 监听
  • sendto,recvfrom 发送、接收数据
  • 关闭Socket对象

Client

#include 
#include 


static const int PORT = 7777;
static const int BUFFER_LENGTH = 128 ;

bool InitWSA() ;

int main()
{
    if(!InitWSA())
    {
        return -1 ;
    }

    SOCKET sockClient = socket (AF_INET, SOCK_DGRAM, 0) ;

    SOCKADDR_IN addrSrv ;
    addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_LOOPBACK) ;
    addrSrv.sin_family = AF_INET ;
    addrSrv.sin_port = htons(PORT) ;

    sendto (sockClient, "Hello, This is Client.\n", strlen("Hello, This is Client.\n") + 1, 0, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR)) ;

    closesocket (sockClient) ;

    WSACleanup () ;

    return 0 ;
}

bool InitWSA()
{
    WORD wVersionRequested;
    WSADATA wsaData;
    int err;

    wVersionRequested = MAKEWORD( 1, 1 );
    err = WSAStartup( wVersionRequested, &wsaData );
    if ( err != 0 ) 
    {                                 
        return false ;
    }
    if ( LOBYTE( wsaData.wVersion ) != 1 ||
        HIBYTE( wsaData.wVersion ) != 1 ) 
    {
        WSACleanup();
        return false ; 
    }
    return true ;
}

UDP Client流程

  • 创建Socket对象
  • connect 连接
  • sendto,recvfrom 发送、接收数据
  • 关闭Socket对象

总结:以上是Windows平台Socket通信最基本的接口展示,其中accept、 connect、send、recv、sendto、recvfrom这几个接口都是阻塞性的,用起来相当不爽.后面将进一步学习Socket的异步IO方案.(不得不吐槽Windows平台的Socket真他妈的丑陋,每次还必须调用WSAStartup,既然都遵循POSIX了,为什么不彻底一点了呢).

源代码请点击这里下载

你可能感兴趣的:(Socket)