Сокет C ++, получающий ошибочные команды, не предназначенные - PullRequest
0 голосов
/ 29 марта 2012

Я изучаю программирование сокетов для использования в будущем проекте, и я довольно подробно исследовал эту проблему.По сути, все, что нужно этой программе - это на клиентском компьютере (локально, то есть на моем компьютере) подключиться к удаленному серверу и отправить команду (что она и сделала, я получил ее, чтобы прочитать мне статистику сервера Apache).

Происходит следующее: я считаю, что сокет настроен правильно, но сервер получает случайные мусорные буферы (один из которых состоит из "'> Z").Я пробовал различные настройки сокетов, разные привязки и т. Д.

Я в процессе запуска инициализирую winsock, создаю сокет, связываю сеть, а затем выполняю цикл прослушивания и while (1) recvданные.

Мне еще нужно получить сервер (на удаленном компьютере, размещенном в центре обработки данных) для вывода сообщения.Это моя единственная цель на данный момент.Я благодарен всем за помощь заранее, и код до (это весь код, извините за длину).

Код клиента:

char *host = "127.0.0.1";
        SOCKET clientsock;
        struct sockaddr_in server_address;

        struct hostent *host_info;

        WSADATA WSAData;
        if(WSAStartup(MAKEWORD(2,2), &WSAData) != -1) {
            cout << "WINSOCK2 Initialized" << endl;         
            if((clientsock = socket(AF_INET, SOCK_STREAM, 0)) != SOCKET_ERROR) {
                cout << "Socket Created" << endl;

                char opt[2];
                opt[0] = 0;
                opt[1] = 1;

                //setsockopt(clientsock, SOL_SOCKET, SO_BROADCAST, opt, sizeof(opt));

                host_info = gethostbyname(host);                    

                server_address.sin_family = AF_INET;
                server_address.sin_addr = *((struct in_addr *)host_info->h_addr);                   
                server_address.sin_port = htons(80);

                if(connect(clientsock, (struct sockaddr *)&server_address, sizeof(struct sockaddr)) == 0) {
                    cout << "Connected to host" << endl;
                    char COMMAND[22] = "SVR --WINSOCK-VERIFY\0";
                    if(send(clientsock, COMMAND, sizeof(COMMAND), 0)) {
                        cout << "Command Sent" << endl;                         
                        closesocket(clientsock);
                    }
                    else {
                        cout << "ERROR - Could not send command. " << "Error: " << WSAGetLastError() << endl;
                        closesocket(clientsock);
                        WSACleanup();
                    }
                }
                else {
                    cout << "ERROR - Could not connect to host. " << "Error: " << WSAGetLastError() << endl;
                    closesocket(clientsock);
                    WSACleanup();
                }                   
            }
            else {
                cout << "ERROR - Could not create the socket. " << "Error: " << WSAGetLastError() << endl;                  
                WSACleanup();
            }               
        }
        else {
            cout << "ERROR - Could not initialize WINSOCK2. " << "Error: " << WSAGetLastError() << endl;                                
            WSACleanup();
        }

Код сервера:

SOCKET serversock;
        char *server = "127.0.0.1";     
        //char *server = "50.31.1.180"; 
        struct sockaddr_in server_address;

        WSADATA WSAData;
        if(WSAStartup(MAKEWORD(2,2), &WSAData) != -1) {
            cout << "WINSOCK2 Initialized" << endl;

            if((serversock = socket(PF_INET, SOCK_DGRAM, PF_UNSPEC)) != SOCKET_ERROR) {
                cout << "Socket Created" << endl;

                unsigned long NB = 1;
                ioctlsocket(serversock, FIONBIO, &NB);

                server_address.sin_family = AF_INET;
                server_address.sin_addr = *((struct in_addr *)server);
                server_address.sin_port = htons(21578); 

                if(bind(serversock, (struct sockaddr*)&server_address, sizeof(struct sockaddr) == 0)) {
                    cout << "Network bound" << endl;                    

                    cout << "Listening..." << endl;
                    listen(serversock, 5);                      
                    while(1) {                  
                        int size = sizeof((struct sockaddr *)server);
                        SOCKET clientsock = accept(serversock, (struct sockaddr *)server, &size);
                        char INCOMMAND[20];
                        if(clientsock >= 0) { 
                            if(recv(clientsock, INCOMMAND, sizeof(INCOMMAND), 0)) {                             
                                int i = 0;  
                                if(INCOMMAND == "SVR --WINSOCK-VERIFY\0") {
                                    cout << "SVR receieved" << endl;
                                }
                                while(INCOMMAND[i] != '\0') {
                                    cout << INCOMMAND[i];                                       
                                    i++;                                                                            
                                }                                   
                                cout << endl;                                   
                            }
                            else {
                                cout << "ERROR - Could not receive command" << endl;
                                break;
                            }
                        }
                    }                       
                }
                else {
                    cout << "ERROR - Could not bind network. " << "Error: " << WSAGetLastError() << endl;
                    closesocket(serversock);
                    WSACleanup();
                }
            }
            else {
                cout << "ERROR - Could not create the socket. " << "Error: " << WSAGetLastError() << endl;                  
                WSACleanup();
            }
        }
        else {
            cout << "ERROR - Could not initialize WINSOCK2. " << "Error: " << WSAGetLastError() << endl;                                
            WSACleanup();
        }

1 Ответ

1 голос
/ 29 марта 2012

Звонки на send / recv могут не отправлять / получать количество байтов, указанное вами в их третьем аргументе, фактически большую часть времени они будут отправлять / получать меньше байтов, чем вы ожидаете.Вы обычно должны зацикливаться, пока все данные не будут отправлены / получены.Также обратите внимание, что при этом:

char buffer[100];
recv(clientsock, buffer, sizeof(buffer), 0);
cout << buffer;

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

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

Edit : Вы должны взглянуть на структуру sockaddr struct.Вы можете взглянуть на это здесь .В вашем коде вы используете это преобразование:

int size = sizeof((struct sockaddr *)"127.0.0.1");

const char *, который является типом "127.0.0.1", не может быть приведен к указателю sockaddr, они несовместимы.Здесь вы должны использовать getaddrinfo для разрешения IP-адреса (обратите внимание, что вы можете использовать доменное имя, и эта функция разрешит его).В Интернете есть множество учебных пособий о том, как использовать эту функцию, просто выполните поиск по запросу «getaddrinfo».

...