2015-05-25 4 views
0

На данный момент я пытаюсь написать программу (C++) для подключения к моему TS3-серверу и запускать запрос.
Для выполнения этой задачи я использую сокет. Сам сокет работает нормально, когда я тестировал его с помощью программы SocketTest (http://sourceforge.net/projects/sockettest/). Тем не менее я не могу подключиться к своему TS3-серверу и запустить запрос.
код я использую (более конкретно функция):Подключение к серверному запросу TeamSpeak с сокетами (C++)

struct sockaddr_in addr; 
WSAStartup(MAKEWORD(1, 1), &wD); 
std::memset(&addr, 0, sizeof(struct sockaddr_in)); 
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 
addr.sin_family = AF_INET; 
addr.sin_port = htons(10011); 
addr.sin_addr.s_addr = inet_addr("127.0.0.1"); 
connect(sock, (struct sockaddr*)&addr, sizeof(addr)); 
send(sock, "use 1\n", sizeof("use 1\n"), MSG_OOB); 
send(sock, "login ****** ********\n", sizeof("login ****** ********\n"), MSG_OOB); 
send(sock, "clientpoke clid=2 msg=Hallo!\n", sizeof("clientpoke clid=2 msg=Hallo!\n"), MSG_OOB); 
closesocket(sock); 
WSACleanup(); 

Если я проверить свой код (в том числе выше функции) с программой SocketTest, все работает, клиент подключается и сервер получает сообщений, но он не работает с моим TS3-сервером. Журналы сервера TS3 не показывают никаких признаков подключения клиента.
Есть ли проблема с моим кодом или есть еще одна причина, почему это не работает с моим TS3-сервером?

P.S .: Я добавил localhost (127.0.0.1) в белый список запросов сервера моего TS3-сервера.
P.S.S .: Я тестировал несколько серверов TS3, все тот же.


РЕШЕНИЕ (Edit):
Решение, кажется, очень легко. Фактически серверный запрос TS3 отправляет данные (приветственные сообщения, ошибки и т. Д.) Всякий раз, когда вы подключаетесь к нему или отправляете команду. Чтобы получить эту работу, мне просто нужно было получить отправленные данные, вот и все.
код будет следующим тогда:

char buffer[1024]; 
struct sockaddr_in addr; 
WSAStartup(MAKEWORD(2, 2), &wD); 
std::memset(&addr, 0, sizeof(struct sockaddr_in)); 
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 
addr.sin_family = AF_INET; 
addr.sin_port = htons(10011); 
addr.sin_addr.s_addr = inet_addr("127.0.0.1"); 
connect(sock, (struct sockaddr*)&addr, sizeof(addr)); 
send(sock, "use 1\n", strlen("use 1\n"), NULL); 
recv(sock, buffer, sizeof(buffer), NULL); 
send(sock, "login Daniel ********\n", strlen("login Daniel ********\n"), NULL); 
recv(sock, buffer, sizeof(buffer), NULL); 
send(sock, "clientpoke clid=1 msg=Hello!\n", strlen("clientpoke clid=1 msg=Hello!\n"), NULL); 
recv(sock, buffer, sizeof(buffer), NULL); 
closesocket(sock); 
WSACleanup(); 

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

(Это также важно, что вы используете sizeof(buffer) вместо strlen(buffer) (или аналогичные вещи) при выполнении команды recv(), в противном случае получение отправленных данных не будет работать.)

+0

Вы можете проверить возвращаемое значение сокета, подключить и отправить функции и/или попросить проводы, чтобы нюхать сообщения –

+0

Как вы знаете, что клиент подключается и получает сервер, если журналы сервера ничего не показывают? Кроме того, вы, похоже, не проверяете ошибки в своем коде. – Galik

ответ

0

Что касается вашего звонка на connect(), то ваш код в порядке, за исключением отсутствия обработки ошибок ,

Но почему вы используете флаг MSG_OOB на send()? Вы не должны использовать это. Кроме того, ваше использование sizeof() при прохождении строковых литералов send() неправильно, используйте strlen() вместо этого, или лучше было бы поместить данные в std::string и передать возвращаемое значение его c_str() и length() методов send().

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

Попробуйте что-то больше, как это:

int sendCommand(SOCKET sock, const std::string &cmd) 
{ 
    const char* ptr = cmd.c_str(); 
    int len = cmd.length(); 

    while (len > 0) 
    { 
     int numSent = send(sock, ptr, len, 0); 
     if (numSent == SOCKET_ERROR) 
      return SOCKET_ERROR; 

     ptr += numSent; 
     len -= numSent; 
    } 

    return 0; 
} 

// TODO: read the response... 

WSADATA wD = {0}; 
int ret = WSAStartup(MAKEWORD(1, 1), &wD); 
if (ret != 0) 
{ 
    // process error as needed ... 
    goto finished; 
} 

SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 
if (sock == INVALID_SOCKET) 
{ 
    ret = WSAGetLastError(); 
    // process error as needed ... 
    goto cleanup; 
} 

struct sockaddr_in addr = {0}; 
addr.sin_family = AF_INET; 
addr.sin_port = htons(10011); 
addr.sin_addr.s_addr = inet_addr("127.0.0.1"); 

if (connect(sock, (struct sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR) 
{ 
    ret = WSAGetLastError(); 
    // process error as needed ... 
    goto donesock; 
} 

// TODO: read the server's initial prompt... 

if (sendCommand(sock, "use 1\n") == SOCKET ERROR) 
{ 
    ret = WSAGetLastError(); 
    // process error as needed ... 
    goto donesock; 
} 

// TODO: read the response... 

if (sendCommand(sock, "login username password\n") == SOCKET_ERROR) 
{ 
    ret = WSAGetLastError(); 
    // process error as needed ... 
    goto donesock; 
} 

// TODO: read the response... 

if (sendCommand(sock, "clientpoke clid=2 msg=Hallo!\n") == SOCKET_ERROR) 
{ 
    ret = WSAGetLastError(); 
    // process error as needed ... 
    goto donesock; 
} 

// TODO: read the response... 

// ... 

if (sendCommand(sock, "logout\n") == SOCKET_ERROR) 
{ 
    ret = WSAGetLastError(); 
    // process error as needed ... 
    goto donesock; 
} 

// TODO: read the response... 

if (sendCommand(sock, "quit\n") == SOCKET_ERROR) 
{ 
    ret = WSAGetLastError(); 
    // process error as needed ... 
    goto donesock; 
} 

donesock: 
closesocket(sock); 

cleanup: 
WSACleanup(); 

finished: 

Вы можете проверить свой сервер TS3, делая то, что следующий форум статьи говорит:

How to use the Server Query

Использование командной строки Telnet приложение для тестирования , Если это не работает, ваше приложение также не будет работать.