Userspace: Implement basic test program for tcp connection
This commit is contained in:
parent
435636a655
commit
b9bbf42538
|
@ -34,6 +34,7 @@ set(USERSPACE_PROJECTS
|
||||||
test-globals
|
test-globals
|
||||||
test-mouse
|
test-mouse
|
||||||
test-sort
|
test-sort
|
||||||
|
test-tcp
|
||||||
test-unix-socket
|
test-unix-socket
|
||||||
touch
|
touch
|
||||||
u8sum
|
u8sum
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
cmake_minimum_required(VERSION 3.26)
|
||||||
|
|
||||||
|
project(test-tcp CXX)
|
||||||
|
|
||||||
|
set(SOURCES
|
||||||
|
main.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
add_executable(test-tcp ${SOURCES})
|
||||||
|
target_compile_options(test-tcp PUBLIC -O2 -g)
|
||||||
|
target_link_libraries(test-tcp PUBLIC libc)
|
||||||
|
|
||||||
|
add_custom_target(test-tcp-install
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/test-tcp ${BANAN_BIN}/
|
||||||
|
DEPENDS test-tcp
|
||||||
|
)
|
|
@ -0,0 +1,111 @@
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
in_addr_t get_ipv4_address(const char* query)
|
||||||
|
{
|
||||||
|
if (in_addr_t ipv4 = inet_addr(query); ipv4 != (in_addr_t)(-1))
|
||||||
|
return ipv4;
|
||||||
|
|
||||||
|
int socket = ::socket(AF_UNIX, SOCK_SEQPACKET, 0);
|
||||||
|
if (socket == -1)
|
||||||
|
{
|
||||||
|
perror("socket");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
sockaddr_un addr;
|
||||||
|
addr.sun_family = AF_UNIX;
|
||||||
|
strcpy(addr.sun_path, "/tmp/resolver.sock");
|
||||||
|
if (connect(socket, (sockaddr*)&addr, sizeof(addr)) == -1)
|
||||||
|
{
|
||||||
|
perror("connect");
|
||||||
|
close(socket);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (send(socket, query, strlen(query), 0) == -1)
|
||||||
|
{
|
||||||
|
perror("send");
|
||||||
|
close(socket);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
sockaddr_storage storage;
|
||||||
|
if (recv(socket, &storage, sizeof(storage), 0) == -1)
|
||||||
|
{
|
||||||
|
perror("recv");
|
||||||
|
close(socket);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
close(socket);
|
||||||
|
|
||||||
|
return *reinterpret_cast<in_addr_t*>(storage.ss_storage);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
if (argc != 2)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "usage: %s IPADDR\n", argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
in_addr_t ipv4 = get_ipv4_address(argv[1]);
|
||||||
|
if (ipv4 == (in_addr_t)(-1))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "could not parse address '%s'\n", argv[1]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int socket = ::socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
if (socket == -1)
|
||||||
|
{
|
||||||
|
perror("socket");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("connecting to %s\n", inet_ntoa({ .s_addr = ipv4 }));
|
||||||
|
|
||||||
|
sockaddr_in server_addr;
|
||||||
|
server_addr.sin_family = AF_INET;
|
||||||
|
server_addr.sin_port = htons(80);
|
||||||
|
server_addr.sin_addr.s_addr = ipv4;
|
||||||
|
if (connect(socket, (sockaddr*)&server_addr, sizeof(server_addr)) == -1)
|
||||||
|
{
|
||||||
|
perror("connect");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char request[128];
|
||||||
|
strcpy(request, "GET / HTTP/1.1\r\n");
|
||||||
|
strcat(request, "Host: "); strcat(request, argv[1]); strcat(request, "\r\n");
|
||||||
|
strcat(request, "Accept: */*\r\n");
|
||||||
|
strcat(request, "Connection: close\r\n");
|
||||||
|
strcat(request, "\r\n");
|
||||||
|
if (send(socket, request, strlen(request), 0) == -1)
|
||||||
|
{
|
||||||
|
perror("send");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char buffer[1024];
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
ssize_t nrecv = recv(socket, buffer, sizeof(buffer), 0);
|
||||||
|
if (nrecv == -1)
|
||||||
|
{
|
||||||
|
perror("recv");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
write(STDOUT_FILENO, buffer, nrecv);
|
||||||
|
}
|
||||||
|
|
||||||
|
close(socket);
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue