support gethostbyname for socket.py

This commit is contained in:
Lyon 2023-07-21 16:51:32 +08:00
parent 31eb011d69
commit 82f0f3dc42
13 changed files with 186 additions and 16 deletions

View File

@ -0,0 +1,28 @@
import socket
# 创建一个socket对象
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 获取服务器的IP地址
server_ip = socket.gethostbyname('pikapython.com')
server_port = 80
# 连接到服务器
s.connect((server_ip, server_port))
# 创建HTTP GET请求
request = 'GET / HTTP/1.1\r\nHost: pikapython.com\r\n\r\n'
s.send(request.encode())
# 接收服务器的响应
response = ''
while True:
recv = s.recv(1024)
if not recv:
break
response += recv.decode()
s.close()
assert 'HTTP/1.1 200 OK' in response
print('PASS')

View File

@ -50,6 +50,32 @@ PIKA_WEAK int pika_platform_connect(int __fd,
#endif
}
PIKA_WEAK int pika_platform_htons(int __hostshort) {
#if defined(__linux__) || PIKA_LWIP_ENABLE
return htons(__hostshort);
#else
WEAK_FUNCTION_NEED_OVERRIDE_ERROR();
#endif
}
/* gethostbyname */
PIKA_WEAK struct hostent* pika_platform_gethostbyname(const char* __name) {
#if defined(__linux__) || PIKA_LWIP_ENABLE
return gethostbyname(__name);
#else
WEAK_FUNCTION_NEED_OVERRIDE_ERROR();
#endif
}
/* inet_ntoa */
PIKA_WEAK char* pika_platform_inet_ntoa(struct in_addr __in) {
#if defined(__linux__) || PIKA_LWIP_ENABLE
return inet_ntoa(__in);
#else
WEAK_FUNCTION_NEED_OVERRIDE_ERROR();
#endif
}
PIKA_WEAK int pika_platform_send(int __fd,
const void* __buf,
size_t __n,

View File

@ -45,6 +45,9 @@ int pika_platform_setsockopt(int __fd,
int __optname,
const void* __optval,
socklen_t __optlen);
int pika_platform_htons(int __hostshort);
char* pika_platform_inet_ntoa(struct in_addr __in);
struct hostent* pika_platform_gethostbyname(const char* __name);
/* os file API */
int pika_platform_close(int fd);

View File

@ -110,13 +110,22 @@ void _socket_socket__listen(PikaObj* self, int num) {
void _socket_socket__connect(PikaObj* self, char* host, int port) {
int sockfd = obj_getInt(self, "sockfd");
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
server_addr.sin_addr.s_addr = inet_addr(host);
struct addrinfo hints, *res;
__platform_memset(&hints, 0, sizeof hints);
hints.ai_family = AF_INET;
if (__platform_getaddrinfo(host, NULL, &hints, &res) != 0) {
obj_setErrorCode(self, PIKA_RES_ERR_RUNTIME_ERROR);
pika_platform_printf("Failed to resolve domain name\n");
return;
}
struct sockaddr_in* server_addr = (struct sockaddr_in*)res->ai_addr;
server_addr->sin_port = pika_platform_htons(port);
pika_GIL_EXIT();
int err = pika_platform_connect(sockfd, (struct sockaddr*)&server_addr,
sizeof(server_addr));
int err = __platform_connect(sockfd, (struct sockaddr*)server_addr,
sizeof(*server_addr));
pika_GIL_ENTER();
if (0 != err) {
obj_setErrorCode(self, PIKA_RES_ERR_RUNTIME_ERROR);
@ -124,13 +133,14 @@ void _socket_socket__connect(PikaObj* self, char* host, int port) {
return;
}
if (obj_getInt(self, "blocking") == 0) {
int flags = fcntl(sockfd, F_GETFL, 0);
if (fcntl(sockfd, F_SETFL, flags | O_NONBLOCK) == -1) {
int flags = pika_platform_fcntl(sockfd, F_GETFL, 0);
if (__platform_fcntl(sockfd, F_SETFL, flags | O_NONBLOCK) == -1) {
obj_setErrorCode(self, PIKA_RES_ERR_RUNTIME_ERROR);
pika_platform_printf("Unable to set socket non blocking\n");
return;
}
}
__platform_freeaddrinfo(res);
}
void _socket_socket__bind(PikaObj* self, char* host, int port) {
@ -155,6 +165,19 @@ char* _socket__gethostname(PikaObj* self) {
return obj_cacheStr(self, hostname);
}
char* _socket__gethostbyname(PikaObj *self, char* host){
struct hostent *host_entry;
char *ip = NULL;
host_entry = pika_platform_gethostbyname(host);
if (host_entry == NULL) {
obj_setErrorCode(self, PIKA_RES_ERR_RUNTIME_ERROR);
__platform_printf("gethostbyname error\n");
return NULL;
}
ip = pika_platform_inet_ntoa(*((struct in_addr *)host_entry->h_addr_list[0]));
return obj_cacheStr(self, ip);
}
void _socket_socket__setblocking(PikaObj* self, int sta) {
obj_setInt(self, "blocking", sta);
}

View File

@ -14,3 +14,4 @@ class socket:
def _gethostname() -> str: ...
def _gethostbyname(host: str) -> str: ...

View File

@ -61,3 +61,6 @@ class socket(_socket.socket):
def gethostname():
return _socket._gethostname()
def gethostbyname(host):
return _socket._gethostbyname(host)

View File

@ -14,3 +14,4 @@ class socket:
def _gethostname() -> str: ...
def _gethostbyname(host: str) -> str: ...

View File

@ -50,6 +50,32 @@ PIKA_WEAK int pika_platform_connect(int __fd,
#endif
}
PIKA_WEAK int pika_platform_htons(int __hostshort) {
#if defined(__linux__) || PIKA_LWIP_ENABLE
return htons(__hostshort);
#else
WEAK_FUNCTION_NEED_OVERRIDE_ERROR();
#endif
}
/* gethostbyname */
PIKA_WEAK struct hostent* pika_platform_gethostbyname(const char* __name) {
#if defined(__linux__) || PIKA_LWIP_ENABLE
return gethostbyname(__name);
#else
WEAK_FUNCTION_NEED_OVERRIDE_ERROR();
#endif
}
/* inet_ntoa */
PIKA_WEAK char* pika_platform_inet_ntoa(struct in_addr __in) {
#if defined(__linux__) || PIKA_LWIP_ENABLE
return inet_ntoa(__in);
#else
WEAK_FUNCTION_NEED_OVERRIDE_ERROR();
#endif
}
PIKA_WEAK int pika_platform_send(int __fd,
const void* __buf,
size_t __n,

View File

@ -45,6 +45,9 @@ int pika_platform_setsockopt(int __fd,
int __optname,
const void* __optval,
socklen_t __optlen);
int pika_platform_htons(int __hostshort);
char* pika_platform_inet_ntoa(struct in_addr __in);
struct hostent* pika_platform_gethostbyname(const char* __name);
/* os file API */
int pika_platform_close(int fd);

View File

@ -110,13 +110,22 @@ void _socket_socket__listen(PikaObj* self, int num) {
void _socket_socket__connect(PikaObj* self, char* host, int port) {
int sockfd = obj_getInt(self, "sockfd");
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
server_addr.sin_addr.s_addr = inet_addr(host);
struct addrinfo hints, *res;
__platform_memset(&hints, 0, sizeof hints);
hints.ai_family = AF_INET;
if (__platform_getaddrinfo(host, NULL, &hints, &res) != 0) {
obj_setErrorCode(self, PIKA_RES_ERR_RUNTIME_ERROR);
pika_platform_printf("Failed to resolve domain name\n");
return;
}
struct sockaddr_in* server_addr = (struct sockaddr_in*)res->ai_addr;
server_addr->sin_port = pika_platform_htons(port);
pika_GIL_EXIT();
int err = pika_platform_connect(sockfd, (struct sockaddr*)&server_addr,
sizeof(server_addr));
int err = __platform_connect(sockfd, (struct sockaddr*)server_addr,
sizeof(*server_addr));
pika_GIL_ENTER();
if (0 != err) {
obj_setErrorCode(self, PIKA_RES_ERR_RUNTIME_ERROR);
@ -124,13 +133,14 @@ void _socket_socket__connect(PikaObj* self, char* host, int port) {
return;
}
if (obj_getInt(self, "blocking") == 0) {
int flags = fcntl(sockfd, F_GETFL, 0);
if (fcntl(sockfd, F_SETFL, flags | O_NONBLOCK) == -1) {
int flags = pika_platform_fcntl(sockfd, F_GETFL, 0);
if (__platform_fcntl(sockfd, F_SETFL, flags | O_NONBLOCK) == -1) {
obj_setErrorCode(self, PIKA_RES_ERR_RUNTIME_ERROR);
pika_platform_printf("Unable to set socket non blocking\n");
return;
}
}
__platform_freeaddrinfo(res);
}
void _socket_socket__bind(PikaObj* self, char* host, int port) {
@ -155,6 +165,19 @@ char* _socket__gethostname(PikaObj* self) {
return obj_cacheStr(self, hostname);
}
char* _socket__gethostbyname(PikaObj *self, char* host){
struct hostent *host_entry;
char *ip = NULL;
host_entry = pika_platform_gethostbyname(host);
if (host_entry == NULL) {
obj_setErrorCode(self, PIKA_RES_ERR_RUNTIME_ERROR);
__platform_printf("gethostbyname error\n");
return NULL;
}
ip = pika_platform_inet_ntoa(*((struct in_addr *)host_entry->h_addr_list[0]));
return obj_cacheStr(self, ip);
}
void _socket_socket__setblocking(PikaObj* self, int sta) {
obj_setInt(self, "blocking", sta);
}

View File

@ -61,3 +61,6 @@ class socket(_socket.socket):
def gethostname():
return _socket._gethostname()
def gethostbyname(host):
return _socket._gethostbyname(host)

View File

@ -291,6 +291,8 @@ TEST(socket, json_issue) {
}
#endif
TEST_RUN_SINGLE_FILE(socket, socket_GET, "test/python/socket/socket_GET.py")
#endif
#if !PIKA_NANO_ENABLE

View File

@ -0,0 +1,28 @@
import socket
# 创建一个socket对象
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 获取服务器的IP地址
server_ip = socket.gethostbyname('pikapython.com')
server_port = 80
# 连接到服务器
s.connect((server_ip, server_port))
# 创建HTTP GET请求
request = 'GET / HTTP/1.1\r\nHost: pikapython.com\r\n\r\n'
s.send(request.encode())
# 接收服务器的响应
response = ''
while True:
recv = s.recv(1024)
if not recv:
break
response += recv.decode()
s.close()
assert 'HTTP/1.1 200 OK' in response
print('PASS')