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

所有最基本的winsock编程都由以下几个基本步骤组成:
 

 

下面来看源码:

 

客户端:

 

#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;
}

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: