No puedo procesar datos recibidos de socket como un bloque

Iniciado por harry_the_blogger, 4 Diciembre 2014, 02:24 AM

0 Miembros y 1 Visitante están viendo este tema.

harry_the_blogger

Hola. Estoy desarrollando algo que podría llamarse "shell remota" porque recibe comandos desde una máquina externa. En realidad es una computadora que está a la escucha de comandos, los interpreta y devuelve un resultado.

El problema está en que yo quiero recibir los carácteres recibidos como un bloque, es decir, como un comando completo. Pero cuando lo intento, pareciera ser que voy recibiendo byte a byte, en vez de toda la informacion transmitida.

Por favor, si pueden ayudarme estaría muy agradecido. Adjunto el código para que vean que el receptor no puede interpretar el comando "ATTACK".

Código (cpp) [Seleccionar]

/* Enlazar Ws2_32 */
#define _WIN32_WINNT 0x0501
#include <stdio.h>
#include <winsock2.h>
#define PUERTO 8080

WSADATA wsa_data;
SOCKET listen_socket, cliente;
struct sockaddr_in clientinfo, servicio;
int rtn;
char buffer[256];

void print_buffer(char *buffer, unsigned int bytes) {
    while(bytes--)
        putchar(*buffer++);

}

int main() {
    if ((rtn = WSAStartup(MAKEWORD(2,2), &wsa_data)) != 0) {
        fprintf(stderr, "Error WSAStartup: %d\n", rtn);
        return 1;
    }

    if((listen_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) {
        fprintf(stderr, "Error en socket: %d\n", WSAGetLastError());
        WSACleanup();
        return 1;
    }

    servicio.sin_family = AF_INET;
    servicio.sin_addr.S_un.S_addr = INADDR_ANY;
    servicio.sin_port = htons(PUERTO);

    if((rtn = bind(listen_socket, (struct sockaddr*) &servicio, (int) sizeof(servicio))) == SOCKET_ERROR) {
        fprintf(stderr, "Error en bind: %d\n", WSAGetLastError());
        WSACleanup();
        return 1;
    }

    if (listen(listen_socket, SOMAXCONN) == SOCKET_ERROR) {
        fprintf(stderr, "Error en listen: %d\n", WSAGetLastError());
        closesocket(listen_socket);
        WSACleanup();
        return 1;
    }

    if((cliente = accept(listen_socket, (struct sockaddr*)&clientinfo, NULL)) == INVALID_SOCKET) {
        fprintf(stderr, "Error en accept: %d\n", WSAGetLastError());
        closesocket(listen_socket);
        WSACleanup();
        return 1;
    }

    closesocket(listen_socket);

    printf("Cliente IP: %s\n", inet_ntoa(clientinfo.sin_addr));

    do {
        rtn = recv(cliente, buffer, sizeof(buffer), 0);

        if(rtn > 0) {
            print_buffer(buffer, rtn);
            if(strcmp(buffer, "ATTACK") == 0){
                printf("ATTACK COMMAND ISSUED!!\n");
            }
        } else if(rtn == 0)
            printf("Cerrando la conexión...\n");
        else {
            fprintf(stderr, "Error en recv: %d\n", WSAGetLastError());
            closesocket(cliente);
            WSACleanup();
            return 1;
        }
    } while(rtn > 0);

    closesocket(cliente);
    WSACleanup();

    return 0;
}

Vista mi blog es enriquemesa.blogspot.com

ivancea96

Tendrás que leer hasta tener un mínimo de bytes, guardándolo todo en una variable. Tras tener la cantidad mínima que necesitas, ya podrás hacer lo que tengas que hacer con ello.

harry_the_blogger

Gracias ivancea96. He implementado una solucion que va contando cada paquete de bytes y los concatena hasta encontrar un CR. Gracias por tu ayuda.
Vista mi blog es enriquemesa.blogspot.com