Подключение к серверу TeamSpeak с помощью сокетов (C ++)

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

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.
П.С.С .: Я протестировал несколько серверов TS3, все так же.


РЕШЕНИЕ (Изменить):
Решение кажется очень простым. Фактически, запрос сервера 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

Решение

Насколько ваш звонок 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, выполнив то, что говорится в следующей статье на форуме:

Как использовать запрос к серверу

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

0

Другие решения


По вопросам рекламы [email protected]