我试图用UDP和SDL_Net 2库编写一个简单的echo服务器。 服务器收到数据包正好并尝试将其发送回它所来自的地址,但客户端没有收到任何内容。
这是我的服务器代码(减去一些已被剥离的无关部分):
void main()
{
/* variables */
if(!(sd = SDLNet_UDP_Open(2000)))
{
printf("Could not create socket\n");
SDLNet_Quit();
exit(1);
}
if(!(p = SDLNet_AllocPacket(512)))
{
printf("Could not allocate packet\n");
SDLNet_Quit();
exit(2);
}
quit = 0;
while(!quit)
{
if(SDLNet_UDP_Recv(sd, p))
{
printf("%s\n", (char*)p->data);
printf("\tFrom port: %d\n", p->address.port);
UDPsocket socket = SDLNet_UDP_Open(0);
if(!socket)
{
printf("Could not create socket to send\n");
}
else
{
printf("\tSending packet\n");
UDPpacket* send = SDLNet_AllocPacket(512);
if(!send)
{
printf("Could not allocate packet to send\n");
}
else
{
send->address = p->address;
send->channel = -1;
send->data = (char*)p->data;
send->len = strlen((char*)send->data) + 1;
send->status = 0;
SDLNet_UDP_Send(socket, -1, send);
}
}
}
}
/* cleanup */
}
所以在服务器端,我基本上是在端口2000上监听传入的数据包,然后在接收数据包时发回一个数据包。
这是客户的代码(再次,部分内容被删除):
void main()
{
SDLNet_Init();
if(!(sd = SDLNet_UDP_Open(0)))
{
printf("Could not create socket\n");
SDLNet_Quit();
SDL_Quit();
exit(1);
}
IPaddress* myaddress = SDLNet_UDP_GetPeerAddress(sd, -1);
if(!myaddress)
{
printf("Could not get own port\n");
exit(2);
}
printf("My port: %d\n", myaddress->port);
UDPpacket* recvp = SDLNet_AllocPacket(512);
if(!recvp)
{
printf("Could not allocate receiving packet\n");
exit(3);
}
UDPsocket socket;
socket = SDLNet_UDP_Open(myaddress->port);
if(!socket)
{
printf("Could not allocate receiving socket\n");
exit(4);
}
// resolve server host
SDLNet_ResolveHost(&srvadd, "localhost", 2000);
if(!(p = SDLNet_AllocPacket(512)))
{
printf("Could not allocate packet\n");
SDLNet_Quit();
SDL_Quit();
exit(2);
}
p->address.host = srvadd.host;
p->address.port = srvadd.port;
/* ... */
while(run)
{
if(SDLNet_UDP_Recv(socket, recvp))
{
printf("Receiving packet\n");
char* data = (char*)recvp->data;
if(strcmp(data, "left") == 0)
{
printf("received left\n");
}
}
SDL_Event e;
while(SDL_PollEvent(&e))
{
if(e.type == SDL_KEYDOWN)
{
switch(e.key.keysym.sym)
{
case SDLK_LEFT:
p->data = "left";
p->len = strlen("left") + 1;
SDLNet_UDP_Send(sd, -1, p);
break;
case SDLK_RIGHT:
p->data = "right";
p->len = strlen("right") + 1;
SDLNet_UDP_Send(sd, -1, p);
break;
default:
break;
}
}
}
}
/* cleanup */
}
因此客户端发送到达服务器的数据包,同时也会监听(但从不听任何事情)。请注意,这些都是非阻塞调用。
我需要做些额外的事吗?我做错了吗?
答案 0 :(得分:1)
我认为问题是你在第一次发送时设置p.address的方式。在文档中声明SDLNet_ResolveHost以网络字节顺序返回IP地址,而不是本机顺序,因此可以从表示127.0.0.1的整数更改为相反的:1.0.0.127。
你可以看到它进行快速调试。希望这可以帮助。此外,文档不是非常精确,因为使用网络订单或本机订单,我不是SDLNet的专家。
答案 1 :(得分:0)
你做了很多错事。 我写了一个简单的服务器:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>
#include "SDL_net.h"
main(int argc, char *argv[]) {
IPaddress serverIP;
UDPsocket udpsock;
UDPpacket* recv_packet;
SDLNet_SocketSet socketset = NULL;
int numused;
static const int MAX_PACKET_SIZE = 512;
if (SDLNet_Init() < 0) {
printf("Couldn't initialize net: %s\n", SDLNet_GetError());
exit(1);
}
udpsock = SDLNet_UDP_Open(3333);
if(!udpsock) {
printf("SDLNet_UDP_Open: %s\n", SDLNet_GetError());
exit(2);
} else {
printf("listening on 0.0.0.0:3333\n");
}
socketset = SDLNet_AllocSocketSet(2);
if ( socketset == NULL ) {
fprintf(stderr, "Couldn't create socket set: %s\n", SDLNet_GetError());
exit(2);
}
numused = SDLNet_UDP_AddSocket(socketset,udpsock);
if(numused==-1) {
printf("SDLNet_AddSocket: %s\n", SDLNet_GetError());
exit(2);
}
recv_packet = SDLNet_AllocPacket(MAX_PACKET_SIZE);
if(!recv_packet) {
printf("Could not allocate packet\n");
exit(2);
}
while(1) {
SDLNet_CheckSockets(socketset, ~0);
if (SDLNet_SocketReady(udpsock)) {
if (SDLNet_UDP_Recv(udpsock, recv_packet)) {
SDLNet_UDP_Send(udpsock, -1, recv_packet);
//format log
int len = recv_packet->len;
char temp[MAX_PACKET_SIZE+2];
memcpy(temp, recv_packet->data, len);
if (temp[len-1] == '\n') {
temp[len-1] = '\\';
temp[len] = 'n';
temp[len+1] = '\0';
} else {
temp[len] = '\0';
}
char hoststring[128];
inet_ntop(AF_INET,&recv_packet->address.host,hoststring,128),
printf("got: \"%s\" from: %s:%d\n",
temp,
hoststring,
ntohs(recv_packet->address.port));
}
}
}
return 0;
}
您可以使用:$ nc -u localhost 3333