Winsock2, связь клиент-сервер - отправка/получение по очереди

Я хочу написать приложение клиент/сервер, в котором клиент и сервер могут обмениваться сообщениями.

Client site communication:

send
recv
send 
recv

Server site communication:

recv
send
recv
send

Однако у меня есть проблема, потому что только одно сообщение отправляется/получается. После этого сокет закрывается и дальнейшие сообщения не отправляются. Что не так и как это исправить? Спасибо.

Код сервера:

#undef UNICODE

#define WIN32_LEAN_AND_MEAN

#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
#pragma comment (lib, "Ws2_32.lib")
#define DEFAULT_PORT "27501"
#define SIZE 1024

int SendAllToClient(SOCKET ClientSocket, char *buffer)
{
    int iSendResult;


    int total = 0, len = 1024;
    int bytesleft = 1024;

    while( total < len )
    {
        iSendResult = send( ClientSocket, buffer, 1024, NULL);

        if (iSendResult == SOCKET_ERROR)
        {
            printf("send failed with error: %d\n", WSAGetLastError());
            closesocket(ClientSocket);
            WSACleanup();
            return 1;
        }
        total += iSendResult;
        bytesleft -= iSendResult;
    }
    printf("Bytes sent: %d\n", iSendResult);

    return total<len?- 1: 1;
}

char *ReadFromClient(SOCKET ConnectSocket)
{
    int iResult;
    char *buffer = new char[1024];
    memset(buffer, 0, 1024);

    do
    {
        iResult = recv(ConnectSocket, buffer, 1024, 0);
        if ( iResult > 0 )
            printf("Bytes received: %d\n", iResult);
        else if ( iResult == 0 )
            printf("Connection closed\n");

        else
            printf("recv failed with error: %d\n", WSAGetLastError());

    }
    while( iResult > 0 );
    return buffer;
}

int main(int argc , char *argv[])
{
    WSADATA wsaData;
    char *buffer;

    SOCKET ListenSocket = INVALID_SOCKET;
    SOCKET ClientSocket = INVALID_SOCKET;

    struct addrinfo *result = NULL;
    struct addrinfo hints;

    int sessionID;
    int iResult;

   // Datagram d1,d2,d3;

    // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
    if (iResult != 0)
    {
        printf("WSAStartup failed with error: %d\n", iResult);
        return 1;
    }

    ZeroMemory(&hints, sizeof(hints));
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;
    hints.ai_flags = AI_PASSIVE;

    // Resolve the server address and port
    iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
    if ( iResult != 0 )
    {
        printf("getaddrinfo failed with error: %d\n", iResult);
        WSACleanup();
        return 1;
    }

    // Create a SOCKET for connecting to server
    ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
    if (ListenSocket == INVALID_SOCKET)
    {
        printf("socket failed with error: %d\n", WSAGetLastError());
        freeaddrinfo(result);
        WSACleanup();
        return 1;
    }

    // Setup the TCP listening socket
    iResult = bind( ListenSocket, result->ai_addr, (int)result->ai_addrlen);
    if (iResult == SOCKET_ERROR)
    {
        printf("bind failed with error: %d\n", WSAGetLastError());
        freeaddrinfo(result);
        closesocket(ListenSocket);
        WSACleanup();
        return 1;
    }

    freeaddrinfo(result);

    iResult = listen(ListenSocket, SOMAXCONN);
    if (iResult == SOCKET_ERROR)
    {
        printf("listen failed with error: %d\n", WSAGetLastError());
        closesocket(ListenSocket);
        WSACleanup();
        return 1;
    }

    printf("Server is listening on localhost:%s ...\n", DEFAULT_PORT);

    // Accept a client socket
    SOCKADDR_IN addr;
    int addrlen = sizeof(addr);

    ClientSocket = accept(ListenSocket, (SOCKADDR*)&addr, &addrlen);
    if (ClientSocket == INVALID_SOCKET)
    {
        printf("accept failed with error: %d\n", WSAGetLastError());
        closesocket(ListenSocket);
        WSACleanup();
        return 1;
    }

    char *ip = inet_ntoa(addr.sin_addr);
    int port = addr.sin_port;
    printf("\nClient %s:%d connected to server\n", ip, port);

    // No longer need server socket
    closesocket(ListenSocket);

    // shutdown the connection since we're done
    iResult = shutdown(ClientSocket, SD_SEND);
    if (iResult == SOCKET_ERROR)
    {
        printf("shutdown failed with error: %d\n", WSAGetLastError());
        closesocket(ClientSocket);
        WSACleanup();
        return 1;
    }

    //read
    buffer = ReadFromClient(ClientSocket);
    printf("FROM CLIENT: %s\n", buffer);
    //send
    memset(buffer, 0, 1024);
    memcpy(buffer, "Hi client, how are you?", strlen("Hi client, how are you?"));
    SendAllToClient(ClientSocket, buffer);
    //read
    //send

    // cleanup
    closesocket(ClientSocket);
    WSACleanup();

    return 0;
}

Код клиента:

#undef UNICODE

#define WIN32_LEAN_AND_MEAN

#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
#pragma comment (lib, "Ws2_32.lib")
#define DEFAULT_PORT "27501"
#define SIZE 1024

int SendAllToServer(SOCKET ServerSocket, char *buffer)
{
    int iSendResult;

    int total = 0, len = 1024;
    int bytesleft = 1024;

    while( total < len )
    {
        iSendResult = send( ServerSocket, buffer, 1024, NULL);

        if (iSendResult == SOCKET_ERROR)
        {
            printf("send failed with error: %d\n", WSAGetLastError());
            closesocket(ServerSocket);
            WSACleanup();
            return 1;
        }
        total += iSendResult;
        bytesleft -= iSendResult;
    }
    printf("Bytes sent: %d\n", iSendResult);

    return total<len?- 1: 1;
}

char *ReadFromServer(SOCKET ConnectSocket)
{
    int iResult;
    char *buffer = new char[1024];
    memset(buffer, 0, 1024);

    do {
        iResult = recv(ConnectSocket, buffer, 1024, 0);
        if ( iResult > 0 )
            printf("Bytes received: %d\n", iResult);
        else if ( iResult == 0 )
            printf("Connection closed\n");

        else
            printf("recv failed with error: %d\n", WSAGetLastError());

    } while( iResult > 0 );
    return buffer;
}

int main(int argc , char *argv[])
{
    WSADATA wsaData;
    SOCKET ConnectSocket = INVALID_SOCKET;
    struct addrinfo *result = NULL,
                    *ptr = NULL,
                    hints;
    char* buffer;
    int sessionID;
    int iResult;
   // Datagram d1,d2;

    // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
    if (iResult != 0) {
        printf("WSAStartup failed with error: %d\n", iResult);
        return 1;
    }

    ZeroMemory( &hints, sizeof(hints) );
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    // Resolve the server address and port
    iResult = getaddrinfo("127.0.0.1", DEFAULT_PORT, &hints, &result);
    if ( iResult != 0 ) {
        printf("getaddrinfo failed with error: %d\n", iResult);
        WSACleanup();
        return 1;
    }

    // Attempt to connect to an address until one succeeds
    for(ptr=result; ptr != NULL ;ptr=ptr->ai_next) {

        // Create a SOCKET for connecting to server
        ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype,
            ptr->ai_protocol);
        if (ConnectSocket == INVALID_SOCKET) {
            printf("socket failed with error: %d\n", WSAGetLastError());
            WSACleanup();
            return 1;
        }

        // Connect to server.
        iResult = connect( ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
        if (iResult == SOCKET_ERROR) {
            closesocket(ConnectSocket);
            ConnectSocket = INVALID_SOCKET;
            continue;
        }
        break;
    }

    freeaddrinfo(result);

    if (ConnectSocket == INVALID_SOCKET) {
        printf("Unable to connect to server!\n");
        WSACleanup();
        return 1;
    }

    //send
    buffer = new char[1024];
    memset(buffer, 0, 1024);
    memcpy(buffer, "Hi server", strlen("Hi server"));
    SendAllToServer(ConnectSocket, buffer);
    //read
    memset(buffer, 0, 1024);
    buffer = ReadFromServer(ConnectSocket);
    printf("FROM SERVER: %s\n", buffer);
    //send
    //read

    // cleanup
    closesocket(ConnectSocket);
    WSACleanup();

    return 0;
}

ИЗМЕНИТЬ

Сервер

#include "data_types.h"
#undef UNICODE

#define WIN32_LEAN_AND_MEAN

#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <iostream>
#pragma comment (lib, "Ws2_32.lib")
#define DEFAULT_PORT "27015"
#define SIZE 1024

int SendAllToClient(SOCKET ClientSocket)
{
    char *buffer = new char[SIZE];
    int iSendResult;
    memset(buffer, 0, SIZE);

    int total = 0, len = SIZE;
    int bytesleft = SIZE;

    while( total < len )
    {
        iSendResult = send( ClientSocket, buffer + total, bytesleft, NULL);

        if (iSendResult == SOCKET_ERROR)
        {
            printf("send failed with error: %d\n", WSAGetLastError());
            closesocket(ClientSocket);
            WSACleanup();
            return 1;
        }
        total += iSendResult;
        bytesleft -= iSendResult;
    }
    printf("Bytes sent: %d\n", iSendResult);
    delete buffer;

    return total<len?- 1: 1;
}

char* ReadFromClient(SOCKET ClientSocket)
{
    std::string data = "";
    char *all = NULL;
    char buffer[1];
    int total = 0, len = SIZE;
    int bytesleft = SIZE;
    int iResult;
    memset(buffer, 0, 1);

    while(total < len)
    {
        if ((iResult = recv(ClientSocket, buffer, 1, 0)) == 0)
        {
            if (errno != 0)
            {
                // cleanup
                closesocket(ClientSocket);
                WSACleanup();
                exit(1);
            }
        }
        data = data + std::string(buffer);
        total += iResult;
        bytesleft -= iResult;
        memset(buffer, 0, 1);
    }
    all = new char[data.length() + 1];
    strcpy(all, data.c_str());

    return all;
}

int main(int argc , char *argv[])
{
    WSADATA wsaData;
    char *buffer;

    SOCKET ListenSocket = INVALID_SOCKET;
    SOCKET ClientSocket = INVALID_SOCKET;

    struct addrinfo *result = NULL;
    struct addrinfo hints;

    int sessionID;
    int iResult;

   // Datagram d1,d2,d3;

    // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
    if (iResult != 0)
    {
        printf("WSAStartup failed with error: %d\n", iResult);
        return 1;
    }

    ZeroMemory(&hints, sizeof(hints));
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;
    hints.ai_flags = AI_PASSIVE;

    // Resolve the server address and port
    iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
    if ( iResult != 0 )
    {
        printf("getaddrinfo failed with error: %d\n", iResult);
        WSACleanup();
        return 1;
    }

    // Create a SOCKET for connecting to server
    ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
    if (ListenSocket == INVALID_SOCKET)
    {
        printf("socket failed with error: %d\n", WSAGetLastError());
        freeaddrinfo(result);
        WSACleanup();
        return 1;
    }

    // Setup the TCP listening socket
    iResult = bind( ListenSocket, result->ai_addr, (int)result->ai_addrlen);
    if (iResult == SOCKET_ERROR)
    {
        printf("bind failed with error: %d\n", WSAGetLastError());
        freeaddrinfo(result);
        closesocket(ListenSocket);
        WSACleanup();
        return 1;
    }

    freeaddrinfo(result);

    iResult = listen(ListenSocket, SOMAXCONN);
    if (iResult == SOCKET_ERROR)
    {
        printf("listen failed with error: %d\n", WSAGetLastError());
        closesocket(ListenSocket);
        WSACleanup();
        return 1;
    }

    printf("Server is listening on localhost:%s ...\n", DEFAULT_PORT);

    // Accept a client socket
    SOCKADDR_IN addr;
    int addrlen = sizeof(addr);

    ClientSocket = accept(ListenSocket, (SOCKADDR*)&addr, &addrlen);
    if (ClientSocket == INVALID_SOCKET)
    {
        printf("accept failed with error: %d\n", WSAGetLastError());
        closesocket(ListenSocket);
        WSACleanup();
        return 1;
    }

    char *ip = inet_ntoa(addr.sin_addr);
    int port = addr.sin_port;
    printf("\nClient %s:%d connected to server\n", ip, port);

    // No longer need server socket
    closesocket(ListenSocket);

    // shutdown the connection since we're done
    iResult = shutdown(ClientSocket, SD_SEND);
    if (iResult == SOCKET_ERROR)
    {
        printf("shutdown failed with error: %d\n", WSAGetLastError());
        closesocket(ClientSocket);
        WSACleanup();
        return 1;
    }

    //read
    buffer = new char[1024];
    memset(buffer, 0, 1024);
    buffer = ReadFromClient(ClientSocket);
    printf("FROM CLIENT: %s\n", buffer);

    //send
    memset(buffer, 0, 1024);
    memcpy(buffer, "Hi client, how are you?", strlen("Hi client, how are you?"));
    // Send an initial buffer
    iResult = send( ClientSocket, buffer, (int)strlen(buffer), 0 );
    if (iResult == SOCKET_ERROR) {
        wprintf(L"send failed with error: %d\n", WSAGetLastError());
        closesocket(ClientSocket);
        WSACleanup();
        return 1;
    }
    //read
    //send

    // cleanup
    closesocket(ClientSocket);
    WSACleanup();

    return 0;
}

Клиент

#include "data_types.h"
#undef UNICODE

#define WIN32_LEAN_AND_MEAN

#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <iostream>
#pragma comment (lib, "Ws2_32.lib")
#define DEFAULT_PORT "27015"
#define SIZE 1024

int SendAllToServer(SOCKET ClientSocket)
{
    char *buffer = new char[SIZE];
    memset(buffer, 0, SIZE);

    int total = 0, len = SIZE;
    int bytesleft = SIZE, iSendResult;

    while( total < len )
    {
        iSendResult = send( ClientSocket, buffer + total, bytesleft, NULL);

        if (iSendResult == SOCKET_ERROR)
        {
            printf("send failed with error: %d\n", WSAGetLastError());
            closesocket(ClientSocket);
            WSACleanup();
            return 1;
        }
        total += iSendResult;
        bytesleft -= iSendResult;
    }
    printf("Bytes sent: %d\n", iSendResult);
    delete buffer;

    return total<len?- 1: 1;
}

char *ReadFromServer(SOCKET ClientSocket)
{
    std::string data = "";
    char *all = NULL;
    char buffer[1];
    int total = 0, len = SIZE;
    int bytesleft = SIZE;
    int iResult;
    memset(buffer, 0, 1);

    while(total < len)
    {
        if ((iResult = recv(ClientSocket, buffer, 1, 0)) == 0)
        {
            if (errno != 0)
            {
                // cleanup
                closesocket(ClientSocket);
                WSACleanup();
                exit(1);
            }
        }
        data = data + std::string(buffer);
        total += iResult;
        bytesleft -= iResult;
        memset(buffer, 0, 1);
    }
    all = new char[data.length() + 1];
    strcpy(all, data.c_str());

    return all;
}

int main(int argc , char *argv[])
{
    WSADATA wsaData;
    SOCKET ConnectSocket = INVALID_SOCKET;
    struct addrinfo *result = NULL,
                    *ptr = NULL,
                    hints;
    char* buffer;
    int sessionID;
    int iResult;
   // Datagram d1,d2;

    // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
    if (iResult != 0) {
        printf("WSAStartup failed with error: %d\n", iResult);
        return 1;
    }

    ZeroMemory( &hints, sizeof(hints) );
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    // Resolve the server address and port
    iResult = getaddrinfo("127.0.0.1", DEFAULT_PORT, &hints, &result);
    if ( iResult != 0 ) {
        printf("getaddrinfo failed with error: %d\n", iResult);
        WSACleanup();
        return 1;
    }

    // Attempt to connect to an address until one succeeds
    for(ptr=result; ptr != NULL ;ptr=ptr->ai_next) {

        // Create a SOCKET for connecting to server
        ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype,
            ptr->ai_protocol);
        if (ConnectSocket == INVALID_SOCKET) {
            printf("socket failed with error: %d\n", WSAGetLastError());
            WSACleanup();
            return 1;
        }

        // Connect to server.
        iResult = connect( ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
        if (iResult == SOCKET_ERROR) {
            closesocket(ConnectSocket);
            ConnectSocket = INVALID_SOCKET;
            continue;
        }
        break;
    }

    freeaddrinfo(result);

    if (ConnectSocket == INVALID_SOCKET) {
        printf("Unable to connect to server!\n");
        WSACleanup();
        return 1;
    }

    //send
    buffer = new char[1024];
    memset(buffer, 0, 1024);
    memcpy(buffer, "Hi server, how are you?", strlen("Hi server, how are you?"));
    // Send an initial buffer
    iResult = send( ConnectSocket, buffer, (int)strlen(buffer), 0 );
    if (iResult == SOCKET_ERROR) {
        closesocket(ConnectSocket);
        WSACleanup();
        return 1;
    }
    //read
    memset(buffer, 0, 1024);
    // Receive until the peer closes the connection
    do {

        iResult = recv(ConnectSocket, buffer, 1024, 0);
        if ( iResult > 0 )
            wprintf(L"Bytes received: %d\n", iResult);
        else if ( iResult == 0 )
            wprintf(L"Connection closed\n");
        else
            wprintf(L"recv failed with error: %d\n", WSAGetLastError());

    } while( iResult > 0 );
    printf("FROM SERVER: %s\n", buffer);
    //send
    //read

    // cleanup
    closesocket(ConnectSocket);
    WSACleanup();

    return 0;
}

person yak    schedule 19.06.2020    source источник
comment
Можете ли вы указать пальцем на настоящие строки кода, которые, как вы утверждаете, должны зацикливаться между отправкой и получением? Таких строк кода нигде не найти. Кроме того, функции отправки и получения полностью нарушены в отношении обработки частичной отправки и получения. ReadFromServer не может реализовать его полностью. SendAllToServer старательно обновляет total и bytesleft, но не может обновить buffer, поэтому частично отправленное сообщение приведет к повторной отправке начала сообщения. Вам также нужно будет решить эти проблемы.   -  person Sam Varshavchik    schedule 19.06.2020
comment
Наконец, обе стороны сокета обрабатываются одним и тем же процессом. Хотя довольно вероятно, что буферы сокетов вашей операционной системы достаточно велики для внутренней буферизации 1024 байтов, у вас нет никаких гарантий на этот счет, поэтому показанный код может в конечном итоге зайти в тупик сам с собой.   -  person Sam Varshavchik    schedule 19.06.2020
comment
@SamVarshavchik: А можно ли, если эти функции будут реализованы должным образом, реализовать такое общение?   -  person yak    schedule 19.06.2020
comment
Конечно, в C++ все возможно.   -  person Sam Varshavchik    schedule 19.06.2020
comment
@SamVarshavchik: Хорошо, не могли бы вы быть так любезны и показать мне, как это исправить?   -  person yak    schedule 19.06.2020
comment
Stackoverflow.com на самом деле не является учебным сайтом по C++, но вы делаете это именно так. Просто возьмите чистый лист бумаги. Запишите, используя короткие, простые предложения на простом английском языке, пошаговый процесс. Когда закончите, позвоните своей резиновой уточке, чтобы договориться о встрече. После того, как ваш резиновый утенок одобрит предложенный вами план действий, просто возьмите то, что вы записали, и переведите его непосредственно на C++. Миссия выполнена!   -  person Sam Varshavchik    schedule 19.06.2020
comment
Во-первых, поскольку вы используете Windows, рассмотрите возможность использования простых оболочек, таких как WSAConnectByName. Во-вторых, клиент/сервер может совместно использовать все функции отправки/получения, потому что после установления соединения нет различия между тем, кто сервер, а кто клиент.   -  person Michael Chourdakis    schedule 21.06.2020
comment
Обработка ошибок после recv выглядит неправильно. Проверьте SOCKET_ERROR и почему вы проверяете errno вместо WSAGetLastError()? errno мог быть установлен более ранним вызовом чего-то другого, но recv не устанавливает его, если только они не забыли упомянуть об этом в документации.   -  person Ted Lyngmo    schedule 22.06.2020


Ответы (2)


Первый выпуск:

    iSendResult = send( ClientSocket, buffer, 1024, NULL);

Это 1024 должно быть bytesleft. Если вы уже прочитали 512 байт, вам не нужно читать больше, чем еще 512.

Это buffer должно быть buffer + total. Если вы уже отправили 512 байт, вам не нужно снова отправлять те же 512 байт, вы хотите отправить другие 512 байт.

Второй вопрос:

Ваша функция ReadFromServer просто полностью сломана и не следует правильной логике. Он возвращает только фатальную ошибку и даже не пытается прочитать ровно 1024 байта. Он просто читает до 1024 байтов, а затем, независимо от того, сколько байтов он фактически прочитал, снова пытается прочитать 1024 байта — и по тому же адресу перезаписывает уже прочитанную часть сообщения!

Она должна работать точно так же, как функция отправки, сначала пытаясь получить 1024 байта и зацикливаясь, если она получает меньше этого, пока либо не получит ровно 1024 байта, либо не получит фатальную ошибку.

Третий вопрос:

    buffer = ReadFromServer(ConnectSocket);
    printf("FROM SERVER: %s\n", buffer);

Не делай этого. Предположим, сервер является вредоносным и отправил вам 1024 байта, которые не являются допустимой строкой в ​​стиле C. Передача этого значения с printf по %s может привести к сбою или неправильному поведению клиента. Всегда относитесь к данным, полученным из сети, как к ненадежным и потенциально опасным. Хотя ваш код будет работать и без исправления этого, в один прекрасный день это сильно вас укусит, и это не очень хорошая привычка.

Вы также должны delete[] буфер, когда вы закончите с ним. Но зачем вообще возвращать необработанный указатель? Вы можете вернуть std::string, std::vector или многие другие гораздо лучшие механизмы, которые избегают риска утечек и делают копии безопасными.

person David Schwartz    schedule 21.06.2020
comment
Чем вы. У меня все еще есть проблемы. Можешь взглянуть? Я добавил код к исходному вопросу - person yak; 22.06.2020
comment
Какая проблема у вас еще есть? Я заметил, что у вас есть delete вместо delete[], а также то, что вы неправильно обрабатываете отправку или получение, возвращая ноль. - person David Schwartz; 26.06.2020
comment
О, вы также делаете это: data = data + std::string(buffer); Это не может работать. Откуда ему знать, сколько байт добавить? (Представьте, если один вызов получает 40 байтов, а следующий вызов получает 10 байтов. Как нулевой байт окажется в конце 10 байтов, полученных во второй раз?) - person David Schwartz; 26.06.2020

На самом деле вы закрываете сокет прослушивания, поэтому, как только будет принято соединение, оно больше не будет принимать:

ClientSocket = accept(ListenSocket, (SOCKADDR*)&addr, &addrlen);
if (ClientSocket == INVALID_SOCKET)
{
    printf("accept failed with error: %d\n", WSAGetLastError());
    closesocket(ListenSocket);
    WSACleanup();
    return 1;
}

char *ip = inet_ntoa(addr.sin_addr);
int port = addr.sin_port;
printf("\nClient %s:%d connected to server\n", ip, port);

// No longer need server socket
closesocket(ListenSocket);

Закрытие прослушивателя предотвращает дальнейшие подключения. Кроме того, вы закрываете клиентский сокет перед его обработкой:

// shutdown the connection since we're done
iResult = shutdown(ClientSocket, SD_SEND);
if (iResult == SOCKET_ERROR)
{
    printf("shutdown failed with error: %d\n", WSAGetLastError());
    closesocket(ClientSocket);
    WSACleanup();
    return 1;
}

//read
buffer = new char[1024];
memset(buffer, 0, 1024);
buffer = ReadFromClient(ClientSocket);
printf("FROM CLIENT: %s\n", buffer);

//send
memset(buffer, 0, 1024);
memcpy(buffer, "Hi client, how are you?", strlen("Hi client, how are you?"));
// Send an initial buffer
iResult = send( ClientSocket, buffer, (int)strlen(buffer), 0 );

Если вы хотите отправить и получить несколько раз, вы должны читать/писать в цикле. Вы делаете это только один раз (и делаете это неправильно): поэтому только одно сообщение, как вы описываете в своем вопросе.

person Manuel    schedule 26.06.2020