C ++ странные данные сокета - PullRequest
1 голос
/ 11 августа 2010

Эй, ребята, вот мой код.

int main() { 

    char buffer[BUFSIZE]; 

    // define our address structure, stores our port
    // and our ip address, and the socket type, etc.. 
    struct sockaddr_in addrinfo; 
    addrinfo.sin_family = AF_INET; 
    addrinfo.sin_port = htons(PORT); 
    addrinfo.sin_addr.s_addr = INADDR_ANY; 


    // create our socket. 
    int sock; 
    if ( (sock = socket(addrinfo.sin_family, SOCK_STREAM, 0))  < 0) { 
        cout << "Error in creating the socket."; 
    } 

    // bind our socket to the actual adress we want 
    if (bind(sock, (struct sockaddr*)&addrinfo, sizeof(addrinfo)) != 0) { 
        cout << "Error in binding."; 
    } 

    // open the socket up for listening
    if (listen(sock, 5) != 0) { 
        cout << "Error in opening listener."; 
    } 
    cout << "Waiting for connections...." << endl; 

    char *msg = "Success! You are connected.\r\n"; 

    // continuously accept new connections.. but no multithreading.. yet
    while(1) { 

        struct sockaddr_in client_addr;
        socklen_t sin_size = sizeof(client_addr); 

        if(int client = accept(sock, (struct sockaddr*)&client_addr, &sin_size)) { 
            cout << "Recived new connection from " << inet_ntoa(client_addr.sin_addr) << endl; 
            send(client, msg, strlen(msg), 0); 
            while(1) { 
                send(client, buffer, recv(client, buffer, BUFSIZE, 0), 0);

                cout << buffer << endl; 
                strcpy(buffer, ""); 
            } 

        } else { 
            cout << "Error in accepting new connection." << endl; 
        } 

    } 

    close(sock); 
    return 0; 
} 

Теперь я очень плохо знаком с сокетами, я просто пытаюсь понять их, но у меня есть некоторый опыт работы с сокетами в PHP.Я использую telnet через putty на моей машине с Linux, чтобы проверить это, я не знаю, вызывает ли это какие-либо проблемы, но сервер выводит некоторые странные символы, и я не знаю почему.Я думаю, что это как-то связано с буфером, но я не совсем уверен.Я могу отправлять такие вещи, как «привет», на сервер через telnet, и он выводит их очень хорошо и отправляет их обратно мне, но когда я отправляю такие вещи, как «hoobla», он запускает прикольные вещи.Любые предложения будут полезны!

Заранее спасибо!

Ответы [ 2 ]

15 голосов
/ 11 августа 2010

Вы получаете распечатанный мусор, потому что recv не завершает ваш буфер нулем.

Важный раздел в приведенном ниже коде:

int num = recv(client,buffer,BUFSIZE,0);
if (num < 1) break;

send(client, ">> ", 3, 0);     // <<-- Nice to have.
send(client, buffer, num, 0);

buffer[num] = '\0';            // <<-- Really important bit!

if (buffer[num-1] == '\n')     // <<-- Nice to have.
    buffer[num-1] = '\0';      // <<-- Nice to have.

cout << buffer << endl;

, который правильно завершитсяВаш буфер перед тем, как пытаться его распечатать, а также удалите завершающий символ новой строки, если он есть (и разрешите клиенту различать строки ввода и отраженные строки).

Эта (полная программа) работает немного лучше:

using namespace std;
#include <iostream>
#include <sys/socket.h>
#include <arpa/inet.h>

#define BUFSIZE 1000
#define PORT 1234

int main() {
    char buffer[BUFSIZE];

    // define our address structure, stores our port
    // and our ip address, and the socket type, etc..
    struct sockaddr_in addrinfo;
    addrinfo.sin_family = AF_INET;
    addrinfo.sin_port = htons(PORT);
    addrinfo.sin_addr.s_addr = INADDR_ANY;

    // create our socket.
    int sock;
    if ( (sock = socket(addrinfo.sin_family, SOCK_STREAM, 0))  < 0) {
        cout << "Error in creating the socket.";
        return -1;
    }

    // bind our socket to the actual adress we want
    if (bind(sock, (struct sockaddr*)&addrinfo, sizeof(addrinfo)) != 0) {
        cout << "Error in binding.";
        return -1;
    }

    // open the socket up for listening
    if (listen(sock, 5) != 0) {
        cout << "Error in opening listener.";
        return -1;
    }

    char *msg = "Success! You are connected.\r\n";

    // continuously accept new connections.. but no multithreading.. yet
    while(1) {
        cout << "Waiting for connections...." << endl;

        struct sockaddr_in client_addr;
        socklen_t sin_size = sizeof(client_addr);

        if(int client =
            accept(sock, (struct sockaddr*)&client_addr, &sin_size))
        {
            cout << "Recieved new connection from "
                << inet_ntoa(client_addr.sin_addr) << endl;
            send(client, msg, strlen(msg), 0);
            while(1) {
                int num = recv(client,buffer,BUFSIZE,0);
                if (num < 1) break;
                send(client, ">> ", 3, 0);
                send(client, buffer, num, 0);

                buffer[num] = '\0';
                if (buffer[num-1] == '\n')
                    buffer[num-1] = '\0';
                cout << buffer << endl;
                strcpy(buffer, "");
            }
        } else {
            cout << "Error in accepting new connection." << endl;
        }
    }
    close(sock);
    return 0;
}

На стороне клиента:

$ telnet 127.0.0.1 1234
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
Success! You are connected.
hello
>> hello
my name is pax
>> my name is pax
and you?
>> and you?
<CTRL-D>
Connection closed by foreign host.

и на стороне сервера:

$ ./testprog
Waiting for connections....
Recived new connection from 127.0.0.1
hello
my name is pax
and you?
Waiting for connections....
1 голос
/ 11 августа 2010

Проблема в том, что buffer не обязательно содержит завершающий строку нулевой символ.Добавьте строку buffer[BUFSIZE-1] = '\0' непосредственно перед вашим cout << buffer.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...