Пример TCP-клиента
От: butcher Россия http://bu7cher.blogspot.com
Дата: 04.10.04 11:07
Оценка: 3 (1)
Здравствуйте,
вот ещё своял.. клиент. Тут сделано на скорую руку, так что могут быть недоработки, но на первый взгляд всё работает.

Клиент соединяется с сервером по введённому адресу и 5678 порту. Может посылать строку текста, принимать данные, определяет завершение сеодинения и сам может завершать соединение. Собственно, коегде по Ctrl+C, кое где по Ctrl+Z.. см. код..
Код, с моей точки зрения, полезен для изучения в режиме дебага, чтобы лучше понимать что где и как..
#include    <iostream>
#include    <winsock2.h>
#include    <windows.h>

#pragma        comment (lib, "ws2_32.lib")

const int    SERVER_PORT        =    5678;
const int    BUF_SIZE        =    65535;

BOOL WINAPI    HandlerRoutine(DWORD);

int main (void)
{
    using                std::cin;
    using                std::cout;
    using                std::endl;
    using                std::cerr;

    WSADATA                wd;
    WSAEVENT            hEvents[2];
    SOCKET                sock;
    WSANETWORKEVENTS    wsEvents;
    SOCKADDR_IN            saddr;
    DWORD                dwDone = 0, dwBreak, dwTimeout;
    int                    nRet;
    char                buf[BUF_SIZE];
    bool                fConnected, fWritePossible;

    if(nRet = WSAStartup(MAKEWORD(2,0), &wd)){
        cerr << "WSAStartup fail with code " << nRet << endl;
        return -1;
    }
    hEvents[0] = static_cast<WSAEVENT>(CreateEvent(NULL, true, false, "StopProgrammEvent"));
    if(!hEvents[0]){
        cerr << "CreateEvent fail with code " << GetLastError () << endl;
        return -2;
    }
    SetConsoleCtrlHandler(HandlerRoutine, true);
    hEvents[1] = WSACreateEvent();
    if (!hEvents[1]){
        cerr << "WSACreateEvent fail with code " << WSAGetLastError() << endl;
        return -3;
    }
    while(!dwDone){
        sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        if(sock == INVALID_SOCKET){
            cerr << "socket fail with code " << WSAGetLastError() << endl;
            return -4;
        }
        cin.clear();
        do{
            cout << "Enter IP address: ";
            cin.getline(buf, BUF_SIZE);
            if(cin.eof() || WaitForSingleObject(hEvents[0], 500) == 0){
                cout << "StopProgrammEvent signaled.. Stopping.." << endl;
                return 0;
            }
        }while(inet_addr(buf) == INADDR_NONE || 
            inet_addr(buf) == INADDR_BROADCAST ||
            inet_addr(buf) == INADDR_ANY);
        
        ZeroMemory(&saddr, sizeof(SOCKADDR_IN));
        saddr.sin_family = AF_INET;
        saddr.sin_port = htons(SERVER_PORT);
        saddr.sin_addr.s_addr = inet_addr(buf);

        if(WSAEventSelect(sock, hEvents[1], FD_CONNECT | FD_READ | FD_WRITE | FD_CLOSE)){
            cerr << "WSAEventSelect fail with code " << WSAGetLastError () << endl;
            return -6;
        }
        cout << "Try connection to " << buf << ":" << SERVER_PORT << "... ";
        nRet = connect(sock, reinterpret_cast<SOCKADDR*>(&saddr), sizeof(SOCKADDR_IN));
        if(nRet == SOCKET_ERROR){
            nRet = WSAGetLastError();
            if(nRet != WSAEWOULDBLOCK){
                cerr << "connect fail with code " << WSAGetLastError() << endl;
                return -7;
            }
        }
        dwBreak = 0; fConnected = false; fWritePossible = true;
        while(!dwBreak && !dwDone){
            if(fConnected && fWritePossible){
                cout << "Type string and press Enter: ";
                cin.getline(buf, BUF_SIZE);
                if(cin.eof()){
                    dwBreak = 1; break;
                }
                nRet = send(sock, buf, lstrlen(buf)+1, 0);
                if(nRet == SOCKET_ERROR){
                    nRet = WSAGetLastError();
                    if(nRet != WSAEWOULDBLOCK){
                        cerr << "send fail with code " << nRet << endl;
                        break;
                    } else {
                        cout << "Process would block, try later.." << endl;
                    }
                } else {
                    cout << "sending " << nRet << " bytes to server." << endl;
                }
                dwTimeout = 1000;
            } else dwTimeout = WSA_INFINITE;
            nRet = WSAWaitForMultipleEvents(2, hEvents, false, dwTimeout, false);
            switch (nRet){
                case WSA_WAIT_TIMEOUT: break;
                case 0:
                    cout << "StopProgrammEvent signaled.. Stopping.." << endl;
                    dwDone = 1;
                    break;
                case 1:
                    if(!WSAEnumNetworkEvents(sock, hEvents[1], &wsEvents)){
                        if(wsEvents.lNetworkEvents & FD_CONNECT){
                            if(wsEvents.iErrorCode[FD_CONNECT_BIT]){
                                cerr << "FD_CONNECT fail witch code " << 
                                  wsEvents.iErrorCode[FD_CONNECT_BIT] << endl;
                                dwBreak = 1;
                            } else {
                                cout << "connected." << endl;
                                fConnected = true;
                            }
                        }
                        if(wsEvents.lNetworkEvents & FD_WRITE){
                            if(wsEvents.iErrorCode[FD_WRITE_BIT]){
                                cerr << "FD_WRITE fail. Stopping.." << endl;
                                dwDone = 1;
                                break;
                            } else {
                                if(!fWritePossible){
                                    nRet = send(sock, buf, lstrlen(buf), 0);
                                    if(nRet == SOCKET_ERROR){
                                        nRet = WSAGetLastError();
                                        if(nRet != WSAEWOULDBLOCK){
                                            cerr << "send fail with code " << nRet << endl;
                                            dwBreak = 1;
                                            break;
                                        } else {
                                            cout << "Process would block, try later.." << endl;
                                        }
                                    } else {
                                        cout << "sending " << nRet << " bytes to server." << endl;
                                    }
                                }
                                fWritePossible = true;
                            }
                        }
                        if(wsEvents.lNetworkEvents & FD_READ){
                            if(wsEvents.iErrorCode[FD_READ_BIT]){
                                cerr << "FD_READ fail. Stopping.." << endl;
                                dwDone = 1;
                                break;
                            } else {
                                nRet = recv(sock, buf, BUF_SIZE, 0);
                                if(nRet > 0) cout << "Received " << nRet << "bytes" << endl;
                            }
                        }
                        if(wsEvents.lNetworkEvents & FD_CLOSE){
                            if(wsEvents.iErrorCode[FD_CLOSE_BIT]){
                                cerr << "FD_CLOSE fail with code " << wsEvents.iErrorCode[FD_CLOSE_BIT] << endl;
                                if(wsEvents.iErrorCode[FD_CLOSE_BIT] == WSAENETDOWN){
                                    cerr << "Stopping.." << endl;
                                    dwDone = 1;
                                } else dwBreak = 1;
                            } else {
                                cout << "Client disconnected." << endl;
                                dwBreak = 1;
                            }
                            break;
                        }
                    } else {
                        cerr << "WSAEnumNetworkEvent fail with code " << WSAGetLastError() << endl;
                        WSAResetEvent(hEvents[2]);
                    }
                    break;
                default:
                    cerr << "WSAWaitForMultipleEvents return " << nRet <<" with error code " 
                         << WSAGetLastError() << endl;
            }
        }
        WSAEventSelect(sock, hEvents[1], 0);
        shutdown(sock, SD_BOTH);
        closesocket(sock);
        cerr << "connection closed.." << endl;
    }
    WSACloseEvent(hEvents[1]);
    CloseHandle(hEvents[0]);
    WSACleanup();
    return 0;
}

BOOL WINAPI    HandlerRoutine(DWORD)
{
    HANDLE    hEvent;
    hEvent = OpenEvent(EVENT_ALL_ACCESS, false, "StopProgrammEvent");
    if(hEvent){
        SetEvent(hEvent);
        CloseHandle(hEvent);
        return true;
    }
    return false;
}

Нет ничего невозможного..
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.