目前我正在尝试编写程序(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服务器的服务器查询白名单中。
P.S.S。:我测试了几台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();
(我知道上面的代码中有没有错误检查,但我有意识地将其删除了。如果您在真实<中运行此代码/ em>环境,你显然需要一些错误检查。
除此之外,我还检查了我的环境中的错误,然后在这里用这段代码说明我的问题。)
(执行sizeof(buffer)
命令时,使用strlen(buffer)
而不是recv()
(或类似的东西)也很重要,否则接收发送的数据会赢得&#39工作。)
答案 0 :(得分:0)
就您对connect()
的调用而言,您的代码很好,除了缺少错误处理。
但为什么要在MSG_OOB
上使用send()
标记?你不应该使用它。此外,在将字符串文字传递给sizeof()
时使用send()
是错误的,请使用strlen()
,或者更好的方法是将数据放入std::string
并传递回报其c_str()
和length()
方法的值为send()
。
此外,您没有阅读TS3服务器发送给客户端的任何响应,因此您不知道您的命令是否实际成功,或者即使您正在与TS3服务器通信也是如此。< / p>
尝试更像这样的事情:
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应用程序进行测试。如果这不起作用,您的应用也无法正常工作。