2015-05-25 68 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:我添加本地主机(127.0.0.1)我TS3服务器的服务器查询白名单。
P.S.S .:我测试了几台TS3服务器,仍然一样。


SOLUTION(编辑):
的解决方案似乎是很容易的。事实上,无论何时连接到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

您可以检查套接字的返回值,连接和发送函数和/或尝试wireshark来嗅探消息 –

+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

用于测试一个命令行远程登录应用程序。如果这不起作用,你的应用程序也不会起作用。

相关问题