我想用C语言为我的世界建立一个假的播放器。
我的Minecraft服务器(bukkit)正在本地IP 192.168.1.141上的端口25565上侦听
当我启动应用程序时(当它通过套接字发送数据时),bukkit服务器会说:“192.168.1.141:XXXXX失去连接”,并且
socked created
socked connected
to send data = (smilie)kekos91;192.168.1.141:25565
to send length = 27
send !
response data = (a strange symbol)
response length = 1
socket disconnected
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <winsock2.h>
int main()
{
char pseudo[] = "kekos91;192.168.1.141:25565";
int pseudoLen = strlen(pseudo);
char *packet = NULL;
packet = (char*)malloc(3 + ((pseudoLen)*sizeof(char)*2));
if(packet == NULL)
{
return -1;
}
memset(packet, '\0', sizeof(packet));
packet[0] = (char)0x02;
strcat(packet, pseudo);
int pLenght = strlen(packet);
char handshake[200];
HANDLE hConsole;
WSADATA wsaData;
int iResult = 0;
SOCKET serverSocket;
sockaddr_in serverInfos;
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != NO_ERROR) {
printf("WSAStartup() failed with error: %d\n", iResult);
return -1;
}
serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (serverSocket == INVALID_SOCKET) {
printf("socket function failed with error: %i\n", WSAGetLastError());
WSACleanup();
return -1;
}
printf("socket created\n");
serverInfos.sin_family = AF_INET;
serverInfos.sin_addr.s_addr = inet_addr("192.168.1.141");
serverInfos.sin_port = htons(25565);
iResult = connect(serverSocket, (SOCKADDR *)&serverInfos, sizeof(serverInfos));
if (iResult == SOCKET_ERROR)
{
printf("connect function failed with error: %i\n", WSAGetLastError());
iResult = closesocket(serverSocket);
if (iResult == SOCKET_ERROR)
{
printf("closesocket function failed with error: %i\n", WSAGetLastError());
}
WSACleanup();
return -1;
}
printf("socket connected\n");
printf("to send data = %s\n", packet);
printf("to send length = %i\n", pseudoLen);
Sleep(500); // after this point, the connection is loose :(
if(send(serverSocket, (char*)packet , pLenght, 0) == SOCKET_ERROR)
{
printf("send function failed with error: %i\n", WSAGetLastError());
iResult = closesocket(serverSocket);
if (iResult == SOCKET_ERROR)
{
printf("closesocket function failed with error: %i\n", WSAGetLastError());
}
WSACleanup();
return -1;
}
free(packet);
printf("send !\n");
if(recv(serverSocket, (char*)&handshake, 200, 0) == SOCKET_ERROR)
{
printf("recv function failed with error: %i\n", WSAGetLastError());
iResult = closesocket(serverSocket);
if (iResult == SOCKET_ERROR)
{
printf("closesocket function failed with error: %i\n", WSAGetLastError());
}
WSACleanup();
return -1;
}
printf("response data = %s\n", handshake);
printf("response length = %i\n", strlen(handshake));
iResult = closesocket(serverSocket);
if (iResult == SOCKET_ERROR) {
printf("closesocket function failed with error %i\n", WSAGetLastError());
WSACleanup();
return -1;
}
printf("socket disconnected.\n");
WSACleanup();
Sleep(5000);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <winsock2.h>
int main()
{
int iSocketResult = 0; // it will retrieve sockets return functions, like send / recv / errors
wchar_t wcPseudo[] = L"kekos91;192.168.1.141:25565";
int iPseudoLen = wcslen(wcPseudo);
char *pPacket = NULL;
pPacket = (char*)malloc(3 + ((iPseudoLen)*sizeof(char)*2));
if(pPacket == NULL)
{
return -1;
}
pPacket[0] = 0x02;
*(short*)( pPacket + 1 ) = htons( iPseudoLen );
memcpy( pPacket + 3, wcPseudo, iPseudoLen * sizeof( wchar_t ));
int iPacketLen = 3 + iPseudoLen*sizeof(wchar_t) ;
char *handshake = NULL;
handshake = (char*)malloc(sizeof(char)*200);
if(handshake == NULL)
{
return -1;
}
HANDLE hConsole;
WSADATA wsaData;
SOCKET serverSocket;
sockaddr_in serverInfos;
iSocketResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iSocketResult != NO_ERROR) {
printf("WSAStartup() failed with error: %d\n", iSocketResult);
return -1;
}
serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (serverSocket == INVALID_SOCKET) {
printf("socket function failed with error: %i\n", WSAGetLastError());
WSACleanup();
return -1;
}
printf("socket created\n");
serverInfos.sin_family = AF_INET;
serverInfos.sin_addr.s_addr = inet_addr("192.168.1.141");
serverInfos.sin_port = htons(25565);
iSocketResult = connect(serverSocket, (SOCKADDR *)&serverInfos, sizeof(serverInfos));
if (iSocketResult == SOCKET_ERROR)
{
printf("connect function failed with error: %i\n", WSAGetLastError());
iSocketResult = closesocket(serverSocket);
if (iSocketResult == SOCKET_ERROR)
{
printf("closesocket function failed with error: %i\n", WSAGetLastError());
}
WSACleanup();
return -1;
}
printf("socket connected\n\n");
printf("to send protocol = %#1.2x \nlenght = %i\n", pPacket[0], iPseudoLen);
iSocketResult = send(serverSocket, pPacket , iPacketLen, 0);
if(iSocketResult == SOCKET_ERROR)
{
printf("send function failed with error: %i\n", WSAGetLastError());
iSocketResult = closesocket(serverSocket);
if (iSocketResult == SOCKET_ERROR)
{
printf("closesocket function failed with error: %i\n", WSAGetLastError());
}
WSACleanup();
return -1;
}
free(pPacket);
printf("send %i (bytes) !\n\n",iSocketResult);
iSocketResult = recv(serverSocket, handshake, 50, 0);
if( iSocketResult == SOCKET_ERROR)
{
printf("recv function failed with error: %i\n", WSAGetLastError());
iSocketResult = closesocket(serverSocket);
if (iSocketResult == SOCKET_ERROR)
{
printf("closesocket function failed with error: %i\n", WSAGetLastError());
}
WSACleanup();
return -1;
}
printf("response protocol = %#1.2x\nresponse lenght = %i (bytes)\n\n", handshake[0], iSocketResult);
free(handshake);
iSocketResult = closesocket(serverSocket);
if (iSocketResult == SOCKET_ERROR)
{
printf("closesocket function failed with error %i\n", WSAGetLastError());
WSACleanup();
return -1;
}
printf("socket disconnected.\n");
WSACleanup();
Sleep(7000);
return 0;
}
输出控制台现在打印:
socket created
socket connected
to send protocol = 0x02
lenght = 27
send 57 (bytes) !
response protocol = 0x02
response lenght = 37 (bytes)
socket disconnected.
感谢你们所有人!
总的来说,你所做的似乎是正确的。我可以想象,当测试代码关闭它自己的套接字时,来自服务器的“连接丢失”消息就会发生。但是,看起来您没有正确地处理字符串数据类型。字符串需要以Unicode的形式发送,而且您似乎是以单字节字符的形式发送的。此外,string前面还需要有表示为2字节整数的长度。
握手字符串可能应该用wchar_t(或您喜欢的宽字符数据类型)指定如下。并在文字上使用L
来指定宽字符串。以字节为单位的实际发送长度需要确保字符串长度乘以2。
wchar_t pseudo[]=L“kekos91;192.168.1.141:25565”;int pseudoLen=wcslen(pseudo);
*((short*)( packet + 1 ) = htons( pseudolLen );
memcpy( packet + 3, pseudo, pseudoLen * sizeof( wchar_t ));
在打印结果响应时,您可能需要以下内容:
printf( "Protocol response: %02x\n", handshake[0] );
然后提取字符串(协议字节后面的两个字节应该是连接哈希字符串的长度(按网络字节顺序)。所以您需要使用ntohs
来提取它。然后下面的N个宽字符表示哈希。
写完所有这些之后,在我看来,您可能想要寻找一个库来处理所有的协议。我没有看过,但似乎有一些与Minecraft相关的C套接字库可用。只是胡乱猜测。再考虑一下,这取决于你的目标。如果您只是想尽可能快地构建客户机,那么寻找库肯定是有意义的。但是,如果您想学习协议、网络编程等的细节,那么按照您开始的级别编写它是一个好主意,而且会很有趣,因为您可以执行渐进的步骤,经常显示真正的结果。
问题内容: 在我的客户端代码中,我正在按照以下步骤连接到套接字: 创建一个套接字 连接它(失败时重试“ x”次) (填写字段后) 使用套接字进行/ 操作: recv(sockDesc, buffer, bufferLen, 0) 套接字描述符并退出 如果在/ 期间断开连接,我发现可以通过返回步骤2进行连接。 这个解决方案可以吗?我应该关闭套接字描述符并返回到步骤1吗? 我无法理解的另一个有趣的观察
始终获得此错误: 我查过这些帖子 套接字失败%1
问题内容: 我的Spring Boot应用程序总是在早上向我显示此whitelabel错误:无法打开JPA EntityManager进行事务;嵌套异常是javax.persistence.PersistenceException:org.hibernate.TransactionException:JDBC开始事务失败: 我在网上搜索,我认为可能是mysql关闭了8个小时的非活动连接。但是,根据
在套接字最终接受另一端消失的情况下,什么指定了这个超时?是操作系统(Ubuntu 11.04),还是来自TCP/IP规范,还是套接字配置选项?
问题内容: 如何创建SSL套接字连接? 我真的需要创建密钥库吗?该密钥库应该与我所有的客户端应用程序共享吗? 我用以下代码创建了一个服务器: 我用以下代码在android上创建了一个客户端: 但是当我尝试连接时,会引发以下错误: 问题答案: 您需要一个证书来建立ssl连接,您可以在密钥库中加载证书,也可以加载证书本身。我将显示一些有关keystore选项的示例。 您的代码需要一些参数才能运行: 您
STOMP 一种简单的消息传递协议,最初创建用于脚本语言,其框架受 HTTP 启发。 STOMP 得到广泛支持,心脏长连接一小时左右失去连接 失去到未定义的连接-建立连接后失去连接非常适合在 WebSocket 和 web 上使用。 SockJS SockJS是WebSocket技术的一种模拟,在表面上,它尽可能使用原生webSocket API,但是再底层非常智能,优先使用原生WebSocket,如果在不支持WebSocket的浏览器中,会自动降为轮询的方式。
一些背景: 我有一个使用3G或4G数据连接的Android应用程序。但它也连接到一个wifi热点,以便在热点设备和应用程序之间传输一些数据。 我想做的是:创建一个到这个wifi热点的套接字连接,并通过这个套接字发送/接收数据。 我添加了以下代码,以确保我们在创建套接字时使用wifi热点wifi(否则它有时最终会使用数据连接): 这似乎没问题。但是,我在尝试连接到远程服务器地址时发现问题。下面是我正