Member 13123405 Ответов: 2

Клиент не может подключиться к серверу с помощью winsock в C++


Я создаю простое клиент-серверное приложение, в котором клиент отправляет файл изображения(.jpg) на сервер. Но клиент не может подключиться к серверу. Пожалуйста, скажите мне, где я ошибаюсь.

Кроме того, если я хочу отправить более 1 изображения, то что я должен для этого сделать? Было бы хорошей идеей использовать общий список для хранения всех изображений, которые я хочу отправить? Как на это пойти? Пожалуйста помочь

Что я уже пробовал:

Клиент:
#include "wcomm.h"
 WSADATA wsaData;
    SOCKET m_socket;
    SOCKET m_backup;
    sockaddr_in con;
    SOCKET AcceptSocket;

    WComm::WComm()
    {

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

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

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

        m_backup = m_socket;


    }
    void WComm::connectServer(char *ip, int port)
    {
        // Connect to a server.
        con.sin_family = AF_INET;
        con.sin_addr.s_addr = inet_addr(ip);
        con.sin_port = htons(port);

        if (connect(m_socket, (SOCKADDR*)&con, sizeof(con)) == SOCKET_ERROR) {
            printf("Failed to connect.\n");
            WSACleanup();
            return;
        }
    }
    int WComm::sendData(char *sendbuf)
    {
        return send(m_socket, sendbuf, strlen(sendbuf), 0);
    }


    int WComm::recvData(char *recvbuf, int size)
    {
        int sz = recv(m_socket, recvbuf, size, 0);
        recvbuf[sz] = '\0';
        return sz;
    }


    void WComm::closeConnection()
    {
        closesocket(m_socket);
        m_socket = m_backup;
    }
    void WComm::fileSend(char *fpath)
    {

        // Extract only filename from given path.
        char filename[50];
        int i = strlen(fpath);
        for (; i>0; i--)
if (fpath[i - 1] == '\\')
break;
        for (int j = 0; i <= (int)strlen(fpath); i++)filename[j++] = fpath[i];
        ifstream myFile(fpath, ios::in | ios::binary | ios::ate);
        int size = (int)myFile.tellg();
        myFile.close();

        char filesize[10]; itoa(size, filesize, 10);


        send(m_socket, filename, strlen(filename), 0);
        char rec[32] = ""; recv(m_socket, rec, 32, 0);

        send(m_socket, filesize, strlen(filesize), 0);
        recv(m_socket, rec, 32, 0);


        FILE *fr = fopen("C:\\Images\\abc.jpg", "rb");

        while (size > 0)
        {
            char buffer[1030];

            if (size >= 1024)
            {
                fread(buffer, 1024, 1, fr);
                send(m_socket, buffer, 1024, 0);
                recv(m_socket, rec, 32, 0);

            }
            else
            {
                fread(buffer, size, 1, fr);
                buffer[size] = '\0';
                send(m_socket, buffer, size, 0);
                recv(m_socket, rec, 32, 0);
            }


            size -= 1024;

        }

        fclose(fr);


    }

WComm w;


    void main(int argc, char *argv[])
    {

    runclient(argv[1], argv[2]);
}
    void runclient(char *ip, char *fpath)
    {
        char rec[32] = "";

        // Connect To Server
        w.connectServer(ip, 27015);
        printf("Connected to server...\n");

        // Sending File
        w.sendData("FileSend"); 
        w.recvData(rec, 32);
        w.fileSend(fpath);
        printf("File Sent.............\n");

        // Send Close Connection Signal
        w.sendData("EndConnection"); w.recvData(rec, 32);
        printf("Connection ended......\n");
    }


Сервер:
#include "wcomm.h"

WSADATA wsaData;
SOCKET m_socket;
SOCKET m_backup;
sockaddr_in con;
SOCKET AcceptSocket;

WComm::WComm()
{

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

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

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

    m_backup = m_socket;


}
void WComm::startServer(int port)
{
    // Connect to a server.
    con.sin_family = AF_INET;
    con.sin_addr.s_addr = inet_addr( "0.0.0.0" );
    con.sin_port = htons( port );

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

    // Listen on the socket.
    if ( listen( m_socket, 1 ) == SOCKET_ERROR )
        printf( "Error listening on socket.\n");

}

void WComm::waitForClient()
{
        AcceptSocket = SOCKET_ERROR;
        while ( AcceptSocket == SOCKET_ERROR ) {
            AcceptSocket = accept( m_backup, NULL, NULL );
        }
        m_socket = AcceptSocket;
}

int WComm::sendData(char *sendbuf)
{
    return send( m_socket, sendbuf, strlen(sendbuf), 0 );
}


int WComm::recvData(char *recvbuf,int size)
{
    int sz = recv( m_socket, recvbuf, size, 0 );
    recvbuf[sz] = '\0';
    return sz;
}


void WComm::closeConnection()
{
    closesocket(m_socket);
    m_socket = m_backup;
}


void WComm::fileReceive(char *filename)
{

    char rec[50] = "";


    recv( m_socket, filename, 32, 0 );
    send( m_socket, "OK", strlen("OK"), 0 );

    FILE *fw = fopen(filename, "wb");

    int recs = recv( m_socket, rec, 32, 0 );
    send( m_socket, "OK", strlen("OK"), 0 );

    rec[recs]='\0';
    int size = atoi(rec);


    while(size > 0)
    {
        char buffer[1030];

        if(size>=1024)
        {
            recv( m_socket, buffer, 1024, 0 );
            send( m_socket, "OK", strlen("OK"), 0 );
            fwrite(buffer, 1024, 1, fw);

        }
        else
        {
            recv( m_socket, buffer, size, 0 );
            send( m_socket, "OK", strlen("OK"), 0 );
            buffer[size]='\0';
            fwrite(buffer, size, 1, fw);
        }


        size -= 1024;

    }

    fclose(fw);

}

WComm w;

void main(int argc, char *argv[])
{
runserver();
}
void runserver()
{
    // Start Server Daemon
    w.startServer(27015);
    printf("Server Started........\n");

    while (TRUE) {

        // Wait until a client connects
        w.waitForClient();
        printf("Client Connected......\n");

        // Work with client
        while (TRUE)
        {
            char rec[50] = "";
            w.recvData(rec, 32); 
            w.sendData("OK");

            if (strcmp(rec, "FileSend") == 0)
            {
                char fname[32] = "";
                w.fileReceive(fname);
                printf("File Received.........\n");
            }


            if (strcmp(rec, "EndConnection") == 0)break;
            printf("Connection Ended......\n");

        }

        // Disconnect client
        w.closeConnection();
    }

}

2 Ответов

Рейтинг:
2

Jochen Arndt

Когда вызов функции сокета завершается неудачно вызовите Функция WSAGetLastError (Windows)[^] и сообщите код ошибки, чтобы узнать, почему он не работает.

Описание кодов ошибок см. В разделе Коды Ошибок Сокетов Windows (Windows)[^].

Обратите внимание также, что у вас есть возможное переполнение буфера в вашем WComm::recvData() функция на

recvbuf[sz] = '\0';
когда size байты были получены и size это размер буфера. Чтобы избежать переполнения буфера, вы должны передать размер буфера минус один.


Рейтинг:
1

Graeme_Grant

Вы пробовали поиск в Google? пример winsock клиентского сервера c++ [^]- Множество примеров на выбор... включая эту статью CodeProject: Простая клиент-серверная сеть с использованием C++ и Windows Winsock[^]