我有2个设备通过远程套接字相互连接,一个是Nintendo 3DS,另一个是我的PC(我的PC中有Windows),并且Nintendo 3DS使用C语言运行,因此服务器套接字将在我的PC上以python运行,客户端套接字将在3DS上以C运行,但是我仍然无法通过套接字连接这两个设备,(服务器拒绝任何直接连接),我不知道为什么我告诉接收连接的人!...
这是我的server.py文件:
import socket;
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM);
s.bind(("192.168.0.25", 8080));
s.listen(5);
while True:
clientsocket, address = s.accept();
print(f"Connection from {address} has been established!");
clientsocket.send(bytes("This is the server!", "utf-8"));
这是我的main.c文件:
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <errno.h>
#include <stdarg.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <3ds.h>
#define MAX 80
#define PORT 8080
#define SA struct sockaddr
int main()
{
gfxInitDefault();
//gfxSet3D(true); //Uncomment if using stereoscopic 3D
consoleInit(GFX_TOP, NULL); //Change this line to consoleInit(GFX_BOTTOM, NULL) if using the bottom screen.
// Main loop
while (aptMainLoop())
{
gspWaitForVBlank();
hidScanInput();
int sockfd;
struct sockaddr_in servaddr;
// socket create and varification
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1) {
printf("socket creation failed...\n");
exit(0);
}
else
printf("Socket successfully created..\n");
bzero(&servaddr, sizeof(servaddr));
// assign IP, PORT
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr("192.168.0.25");
servaddr.sin_port = htons(PORT);
// connect the client socket to server socket
if (connect(sockfd, (SA*)&servaddr, sizeof(servaddr)) != 0) {
printf("connection with the server failed...\n");
exit(0);
}
else
printf("connected to the server..\n");
// close the socket
close(sockfd);
u32 kDown = hidKeysDown();
if (kDown & KEY_START)
break; //Break in order to return to hbmenu
// Flush and swap frame-buffers
gfxFlushBuffers();
gfxSwapBuffers();
}
gfxExit();
return 0;
}
但是当我在3DS上运行客户端时,我仍然无法连接到python服务器(在3DS上打印失败消息)。
所以现在我不知道为什么它不起作用!,我知道很难测试代码,因为它需要模拟3ds系统才能使用3ds.h库。
(但这并不是真正必要的,3ds.h库仅具有用于初始化应用程序和系统控件的内容),但是...如果仅查看客户端内容,则不包括3ds.h库代码,该代码可以用2种不同的设备(不一定是3DS)(例如PC到PC)进行测试,那么,¿代码有什么问题?
我知道3DS可以充当客户端或服务器套接字的角色,并且她可以创建套接字,因为我直接在3DS中运行了另一个在3DS中基于Web建立的示例,它直接在3DS.h套接字示例中起作用了。 / p>
但是在该示例中,与3DS套接字服务器连接的唯一方法是在创建套接字时转到3DS消息给出的地址,例如:http://192.168.0.27,但是当我打开标签在浏览器中,我需要在python文件中获取这些信息值!,我需要在不位于网页中的python文件中接收它们...我试图与python连接,但这次是python客户端(我修改了addres在运行3DS的服务器套接字时进行连接),因此这是为我创建的用于该示例情况的client.py:
import socket;
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM);
s.connect(("192.168.0.30",2000));// Port depends on 3DS assignement
msg = s.recv(1024);
print(msg.decode("utf-8"));
但是在我的3DS中,当我连接到PC上的页面时,打印3行,在所有情况下ip都是相同的,但是端口是不同的,所以我修改了服务器连接哪个client.py的端口正在运行,我尝试通过服务器与PC连接,但仍然保持不变,它使我在终端上的PC客户端上拒绝连接消息……因此我都不知道(两种情况下3DS都在做服务器)和PC做客户端,或PC做服务器和3DS做客户端),结果是一样的,我无法连接两个设备。
这是我在带有3ds.h库的3DS上找到的套接字的示例:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <errno.h>
#include <stdarg.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <3ds.h>
#define SOC_ALIGN 0x1000
#define SOC_BUFFERSIZE 0x100000
static u32 *SOC_buffer = NULL;
s32 sock = -1, csock = -1;
__attribute__((format(printf,1,2)))
void failExit(const char *fmt, ...);
const static char http_200[] = "HTTP/1.1 200 OK\r\n";
const static char indexdata[] = "<html> \
<head><title>A test page</title></head> \
<body> \
This small test page has had %d hits. \
</body> \
</html>";
const static char http_html_hdr[] = "Content-type: text/html\r\n\r\n";
const static char http_get_index[] = "GET / HTTP/1.1\r\n";
//---------------------------------------------------------------------------------
void socShutdown() {
//---------------------------------------------------------------------------------
printf("waiting for socExit...\n");
socExit();
}
//---------------------------------------------------------------------------------
int main(int argc, char **argv) {
//---------------------------------------------------------------------------------
int ret;
u32 clientlen;
struct sockaddr_in client;
struct sockaddr_in server;
char temp[1026];
static int hits=0;
gfxInitDefault();
// register gfxExit to be run when app quits
// this can help simplify error handling
atexit(gfxExit);
consoleInit(GFX_TOP, NULL);
printf ("\nlibctru sockets demo\n");
// allocate buffer for SOC service
SOC_buffer = (u32*)memalign(SOC_ALIGN, SOC_BUFFERSIZE);
if(SOC_buffer == NULL) {
failExit("memalign: failed to allocate\n");
}
// Now intialise soc:u service
if ((ret = socInit(SOC_buffer, SOC_BUFFERSIZE)) != 0) {
failExit("socInit: 0x%08X\n", (unsigned int)ret);
}
// register socShutdown to run at exit
// atexit functions execute in reverse order so this runs before gfxExit
atexit(socShutdown);
// libctru provides BSD sockets so most code from here is standard
clientlen = sizeof(client);
sock = socket (AF_INET, SOCK_STREAM, IPPROTO_IP);
if (sock < 0) {
failExit("socket: %d %s\n", errno, strerror(errno));
}
memset (&server, 0, sizeof (server));
memset (&client, 0, sizeof (client));
server.sin_family = AF_INET;
server.sin_port = htons (80);
server.sin_addr.s_addr = gethostid();
printf("Point your browser to http://%s/\n",inet_ntoa(server.sin_addr));
if ( (ret = bind (sock, (struct sockaddr *) &server, sizeof (server))) ) {
close(sock);
failExit("bind: %d %s\n", errno, strerror(errno));
}
// Set socket non blocking so we can still read input to exit
fcntl(sock, F_SETFL, fcntl(sock, F_GETFL, 0) | O_NONBLOCK);
if ( (ret = listen( sock, 5)) ) {
failExit("listen: %d %s\n", errno, strerror(errno));
}
while (aptMainLoop()) {
gspWaitForVBlank();
hidScanInput();
csock = accept (sock, (struct sockaddr *) &client, &clientlen);
if (csock<0) {
if(errno != EAGAIN) {
failExit("accept: %d %s\n", errno, strerror(errno));
}
} else {
// set client socket to blocking to simplify sending data back
fcntl(csock, F_SETFL, fcntl(csock, F_GETFL, 0) & ~O_NONBLOCK);
printf("Connecting port %d from %s\n", client.sin_port, inet_ntoa(client.sin_addr));
memset (temp, 0, 1026);
ret = recv (csock, temp, 1024, 0);
if ( !strncmp( temp, http_get_index, strlen(http_get_index) ) ) {
hits++;
send(csock, http_200, strlen(http_200),0);
send(csock, http_html_hdr, strlen(http_html_hdr),0);
sprintf(temp, indexdata, hits);
send(csock, temp, strlen(temp),0);
}
close (csock);
csock = -1;
}
u32 kDown = hidKeysDown();
if (kDown & KEY_START) break;
}
close(sock);
return 0;
}
//---------------------------------------------------------------------------------
void failExit(const char *fmt, ...) {
//---------------------------------------------------------------------------------
if(sock>0) close(sock);
if(csock>0) close(csock);
va_list ap;
printf(CONSOLE_RED);
va_start(ap, fmt);
vprintf(fmt, ap);
va_end(ap);
printf(CONSOLE_RESET);
printf("\nPress B to exit\n");
while (aptMainLoop()) {
gspWaitForVBlank();
hidScanInput();
u32 kDown = hidKeysDown();
if (kDown & KEY_B) exit(0);
}
}
这是我找到该示例时的页面:
https://smealum.github.io/ctrulib/3ds_8h.html
具体来说:
#include <3ds/services/soc.h>