From the archive

winsock客户/服务器端基本编程

所有最基本的winsock编程都由以下几个基本步骤组成:
 
  • About Servers and Clients
  • Creating a Basic Winsock Application
  • Initializing Winsock
  • Creating a Socket
  • Binding a Socket
  • Listening on a Socket
  • Accepting a Connection
  • Connecting to a Socket
  • Sending and Receiving Data
  • Complete Server and Client Code
  •  

    下面来看源码:

     

    客户端:

     

    #include <stdio.h>
    #include "winsock2.h"

    void main() {

        // Initialize Winsock.
        WSADATA wsaData;

    //WSADATA,大概就是winsock api data 的缩写,一个类,指定了一个叫做wsaData的Object.这个Object干吗用的呢?

        int iResult = WSAStartup( MAKEWORD(2,2), &wsaData );

    //调用一个winsock lib的启动函数,指定版本为2.2, 并且把刚才创立的Object扔了进去.

        if ( iResult != NO_ERROR )
            printf("Error at WSAStartup()\n");
    //如果上面的函数没成功就写个信息.

        // Create a socket.
        SOCKET m_socket;
    //SOCKET这个类是此类编程的重点,就是创立一个和主机有关的通信对象,里头包含有主机的ip地址,host name,端口等信息

     

        m_socket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
    //给我们创立的主机通信对象设置好ip地址是internet形的,传输方式是stream,以及使用TCP协议.

        if ( m_socket == INVALID_SOCKET ) {
            printf( "Error at socket(): %ld\n", WSAGetLastError() );
            WSACleanup();
            return;
        }
    //出错就关闭winsock并弹出程序

        // Connect to a server.
        sockaddr_in clientService;
    //用sockaddr这个类创立一个用来存目标主机地址,端口的object.

        clientService.sin_family = AF_INET;
        clientService.sin_addr.s_addr = inet_addr( "127.0.0.1" );
        clientService.sin_port = htons( 27015 );

    //指定这个主机的地址,端口等信息.

        if ( connect( m_socket, (SOCKADDR*) &clientService, sizeof(clientService) ) == SOCKET_ERROR) {
            printf( "Failed to connect.\n" );
            WSACleanup();
            return;
        }

    //把地址信息对象,socket对象扔进这个叫做connect的函数里头,连接一下,失败就退.

        // Send and receive data.
        int bytesSent;
        int bytesRecv = SOCKET_ERROR;
        char sendbuf[32] = "Client: Sending data.";
        char recvbuf[32] = "";

        bytesSent = send( m_socket, sendbuf, strlen(sendbuf), 0 );
        printf( "Bytes Sent: %ld\n", bytesSent );

    //发送一段32字节的信息:"Client: Sending data."给主机.

        if ( bytesRecv == 0 ||
            (bytesRecv == SOCKET_ERROR &&
             WSAGetLastError()== WSAECONNRESET ))
        {
            bytesRecv = recv( m_socket, recvbuf, 32, 0 );
            if ( bytesRecv == -1 )
            {
                printf( "Connection Closed.\n");
                break;
            }
            if (bytesRecv < 0)
                return;
            printf( "Bytes Recv: %ld\n", bytesRecv );
        }
    //接受一段32字节的信息.哎,接受信息是主动的.把这里看成是cin好了

        WSACleanup();
        return;

    }

     

    服务器端

    基本没啥特别,就是服务器的winsock开启后用一个while loop来等带连接.

    #include <stdio.h>
    #include "winsock2.h"

    void main() {

        // Initialize Winsock.
        WSADATA wsaData;
        int iResult = WSAStartup( MAKEWORD(2,2), &wsaData );
        if ( iResult != NO_ERROR )
            printf("Error at WSAStartup()\n");

        // Create a socket.
        SOCKET m_socket;
        m_socket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );

        if ( m_socket == INVALID_SOCKET ) {
            printf( "Error at socket(): %ld\n", WSAGetLastError() );
            WSACleanup();
            return;
        }

        // Bind the socket.
        sockaddr_in service;

        service.sin_family = AF_INET;
        service.sin_addr.s_addr = inet_addr( "127.0.0.1" );
        service.sin_port = htons( 27015 );

        if ( bind( m_socket, (SOCKADDR*) &service, sizeof(service) ) == SOCKET_ERROR ) {
            printf( "bind() failed.\n" );
            closesocket(m_socket);
            return;
        }
       
        // Listen on the socket.
        if ( listen( m_socket, 1 ) == SOCKET_ERROR )
            printf( "Error listening on socket.\n");

        // Accept connections.
        SOCKET AcceptSocket;

        printf( "Waiting for a client to connect…\n" );

     

    //就是这里了,一个while loop,等accept函数成功后就退出等待状态.

        while (1) {
            AcceptSocket = SOCKET_ERROR;
            while ( AcceptSocket == SOCKET_ERROR ) {
                AcceptSocket = accept( m_socket, NULL, NULL );
            }
            printf( "Client Connected.\n");
            m_socket = AcceptSocket;
            break;
        }
       
        // Send and receive data.
        int bytesSent;
        int bytesRecv = SOCKET_ERROR;
        char sendbuf[32] = "Server: Sending Data.";
        char recvbuf[32] = "";
       
        bytesRecv = recv( m_socket, recvbuf, 32, 0 );
        printf( "Bytes Recv: %ld\n", bytesRecv );
       
        bytesSent = send( m_socket, sendbuf, strlen(sendbuf), 0 );
        printf( "Bytes Sent: %ld\n", bytesSent );

        WSACleanup();
        return;
    }

    Archiveretrieving memory…