Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Temas - kukuruznom

#1
Hola, tengo un problema, bueno, muchos problemas con Winsock. Ya he programado algo similar una vez en Linux y no me pareció tan complicado. El problema es que ahora, aunque el servidor compila correctamente, no reenvía los mensajes, o no sé qué es lo que realmente está funcionando mal.
Obtuve gran parte de la información de aquí: No tienes permitido ver los links. Registrarse o Entrar a mi cuenta.
Intenté utilizar ChatGPT y Perplexity, pero tampoco resolvieron nada.
Encontré esto, pero es de hace más de diez años: No tienes permitido ver los links. Registrarse o Entrar a mi cuenta.
Y lo que encontré que sí funciona es para Linux.
A continuacion les dejo mi codigo:
server:
Código: php
#include <iostream>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <string>
#include <vector>
#include <memory>

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

#define DEFAULT_BUFLEN 512

using namespace std;

int main() {
    WSADATA wsaData;
    int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (iResult != 0) {
        cerr << "WSAStartup falló: " << iResult << endl;
        return 1;
    }

    string ipAddress;
    string port;

    cout << "Ingrese la dirección IP del servidor: ";
    cin >> ipAddress;

    cout << "Ingrese el puerto del servidor: ";
    cin >> port;

    struct addrinfo* result = NULL;
    struct addrinfo hints;

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

    iResult = getaddrinfo(ipAddress.c_str(), port.c_str(), &hints, &result);
    if (iResult != 0) {
        cerr << "getaddrinfo falló: " << iResult << endl;
        WSACleanup();
        return 1;
    }

    SOCKET ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
    if (ListenSocket == INVALID_SOCKET) {
        cerr << "Error en socket(): " << WSAGetLastError() << endl;
        freeaddrinfo(result);
        WSACleanup();
        return 1;
    }

    iResult = bind(ListenSocket, result->ai_addr, (int)result->ai_addrlen);
    if (iResult == SOCKET_ERROR) {
        cerr << "bind falló con error: " << WSAGetLastError() << endl;
        freeaddrinfo(result);
        closesocket(ListenSocket);
        WSACleanup();
        return 1;
    }

    freeaddrinfo(result);

    iResult = listen(ListenSocket, SOMAXCONN);
    if (iResult == SOCKET_ERROR) {
        cerr << "listen falló con error: " << WSAGetLastError() << endl;
        closesocket(ListenSocket);
        WSACleanup();
        return 1;
    }

    cout << "Servidor iniciado. Esperando conexiones en " << ipAddress << ":" << port << "..." << endl;

    vector<unique_ptr<SOCKET>> clientSockets;

    while (true) {
        SOCKET ClientSocket = accept(ListenSocket, NULL, NULL);
        if (ClientSocket == INVALID_SOCKET) {
            cerr << "accept falló: " << WSAGetLastError() << endl;
            closesocket(ListenSocket);
            WSACleanup();
            return 1;
        }

        clientSockets.push_back(make_unique<SOCKET>(ClientSocket));

        cout << "Cliente conectado." << endl;

        string nickname;
        char recvbuf[DEFAULT_BUFLEN];
        int iSendResult;

        iResult = recv(ClientSocket, recvbuf, DEFAULT_BUFLEN, 0);
        if (iResult > 0) {
            recvbuf[iResult] = '\0';
            nickname = recvbuf;
            cout << "Nickname del cliente: " << nickname << endl;
        }

        for (auto it = clientSockets.begin(); it != clientSockets.end(); ++it) {
            if (**it != ClientSocket) {
                string message = nickname + " se ha conectado.";
                iSendResult = send(**it, message.c_str(), message.size(), 0);
                if (iSendResult == SOCKET_ERROR) {
                    cerr << "send falló: " << WSAGetLastError() << endl;
                    closesocket(**it);
                    clientSockets.erase(it);
                }
            }
        }

        while (true) {
            iResult = recv(ClientSocket, recvbuf, DEFAULT_BUFLEN, 0);
            if (iResult > 0) {
                recvbuf[iResult] = '\0';
                string message = nickname + ": " + recvbuf;
                for (auto it = clientSockets.begin(); it != clientSockets.end(); ++it) {
                    if (**it != ClientSocket) {
                        iSendResult = send(**it, message.c_str(), message.size(), 0);
                        if (iSendResult == SOCKET_ERROR) {
                            cerr << "send falló: " << WSAGetLastError() << endl;
                            closesocket(**it);
                            clientSockets.erase(it);
                        }
                    }
                }
            }
            else if (iResult == 0) {
                cout << "Cliente desconectado." << endl;
                for (auto it = clientSockets.begin(); it != clientSockets.end(); ++it) {
                    if (**it != ClientSocket) {
                        string message = nickname + " se ha desconectado.";
                        iSendResult = send(**it, message.c_str(), message.size(), 0);
                        if (iSendResult == SOCKET_ERROR) {
                            cerr << "send falló: " << WSAGetLastError() << endl;
                            closesocket(**it);
                            clientSockets.erase(it);
                        }
                    }
                }
                closesocket(ClientSocket);
                break;
            }
            else {
                cerr << "recv falló: " << WSAGetLastError() << endl;
                closesocket(ClientSocket);
                break;
            }
        }
    }

    WSACleanup();
    return 0;
}
cliente
Código: php
#include <iostream>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <string>

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

using namespace std;

int main(int argc, char* argv[]) {
    WSADATA wsaData;
    int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (iResult != 0) {
        cerr << "WSAStartup falló: " << iResult << endl;
        return 1;
    }

    struct addrinfo* result = NULL, * ptr = NULL, hints;

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

    string serverIP;
    cout << "Ingrese la IP del servidor: ";
    cin >> serverIP;

    string port;
    cout << "Ingrese el puerto: ";
    cin >> port;

    string nickname;
    cout << "Ingrese el apodo: ";
    cin >> nickname;

    iResult = getaddrinfo(serverIP.c_str(), port.c_str(), &hints, &result);
    if (iResult != 0) {
        cerr << "getaddrinfo falló: " << iResult << endl;
        WSACleanup();
        return 1;
    }

    SOCKET ConnectSocket = INVALID_SOCKET;
    for (ptr = result; ptr != NULL; ptr = ptr->ai_next) {
        ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
        if (ConnectSocket == INVALID_SOCKET) {
            cerr << "Error en socket(): " << WSAGetLastError() << endl;
            freeaddrinfo(result);
            WSACleanup();
            return 1;
        }

        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) {
        cerr << "¡No se pudo conectar al servidor!" << endl;
        WSACleanup();
        return 1;
    }

    cout << "Conectado al servidor." << endl;

    iResult = send(ConnectSocket, nickname.c_str(), nickname.size(), 0);
    if (iResult == SOCKET_ERROR) {
        cerr << "send falló: " << WSAGetLastError() << endl;
        closesocket(ConnectSocket);
        WSACleanup();
        return 1;
    }

    char recvbuf[512];
    int iSendResult;

    while (true) {
        string message;
        getline(cin, message);
        message = nickname + ": " + message;
        iResult = send(ConnectSocket, message.c_str(), message.size(), 0);
        if (iResult == SOCKET_ERROR) {
            cerr << "send falló: " << WSAGetLastError() << endl;
            closesocket(ConnectSocket);
            WSACleanup();
            return 1;
        }
    }

    iResult = shutdown(ConnectSocket, SD_SEND);
    if (iResult == SOCKET_ERROR) {
        cerr << "shutdown falló: " << WSAGetLastError() << endl;
        closesocket(ConnectSocket);
        WSACleanup();
        return 1;
    }

    closesocket(ConnectSocket);
    WSACleanup();

    return 0;
}
Si alguien conoce otra forma de hacerlo sin Winsock o lo ha hecho antes, estaría agradecido si pudiera ver cómo lo hicieron.