Compare commits
7 Commits
fc8e190d0a
...
43736dbe0f
Author | SHA1 | Date | |
---|---|---|---|
43736dbe0f | |||
fed19bda4c | |||
e8a079c68c | |||
630e49571a | |||
0575eaa4cc | |||
c07cd75d39 | |||
39470121df |
17
~/Bash/unix-socket-server.sh
Executable file
17
~/Bash/unix-socket-server.sh
Executable file
@ -0,0 +1,17 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# TCP
|
||||||
|
#coproc nc -l localhost 3000
|
||||||
|
|
||||||
|
# UnixSocket
|
||||||
|
coproc nc -l -U ./app.sock
|
||||||
|
|
||||||
|
while read -r cmd; do
|
||||||
|
case $cmd in
|
||||||
|
d) date ;;
|
||||||
|
q) break ;;
|
||||||
|
*) echo 'Try again?'
|
||||||
|
esac
|
||||||
|
done <&"${COPROC[0]}" >&"${COPROC[1]}"
|
||||||
|
|
||||||
|
kill "$COPROC_PID"
|
38
~/C/AF_INET_sockets/echo_client.c
Normal file
38
~/C/AF_INET_sockets/echo_client.c
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
/* https://rsdn.org/article/unix/sockets.xml */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
|
||||||
|
char message[] = "Hello there!\n";
|
||||||
|
char buf[sizeof(message)];
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
int sock;
|
||||||
|
struct sockaddr_in addr;
|
||||||
|
|
||||||
|
sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
if (sock < 0) {
|
||||||
|
perror("socket");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
addr.sin_family = AF_INET;
|
||||||
|
addr.sin_port = htons(3425); // или любой другой порт...
|
||||||
|
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||||
|
if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
|
||||||
|
perror("connect");
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
send(sock, message, sizeof(message), 0);
|
||||||
|
recv(sock, buf, sizeof(message), 0);
|
||||||
|
|
||||||
|
printf(buf);
|
||||||
|
close(sock);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
48
~/C/AF_INET_sockets/echo_server.c
Normal file
48
~/C/AF_INET_sockets/echo_server.c
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
/* https://rsdn.org/article/unix/sockets.xml */
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
int sock, listener;
|
||||||
|
struct sockaddr_in addr;
|
||||||
|
char buf[1024];
|
||||||
|
int bytes_read;
|
||||||
|
|
||||||
|
listener = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
if (listener < 0) {
|
||||||
|
perror("socket");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
addr.sin_family = AF_INET;
|
||||||
|
addr.sin_port = htons(3425);
|
||||||
|
addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||||
|
if (bind(listener, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
|
||||||
|
perror("bind");
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
listen(listener, 1);
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
sock = accept(listener, NULL, NULL);
|
||||||
|
if (sock < 0) {
|
||||||
|
perror("accept");
|
||||||
|
exit(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
bytes_read = recv(sock, buf, 1024, 0);
|
||||||
|
if (bytes_read <= 0) break;
|
||||||
|
send(sock, buf, bytes_read, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
close(sock);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
BIN
~/C/unixsocket/a.out
Executable file
BIN
~/C/unixsocket/a.out
Executable file
Binary file not shown.
BIN
~/C/unixsocket/client
Executable file
BIN
~/C/unixsocket/client
Executable file
Binary file not shown.
79
~/C/unixsocket/client.c
Normal file
79
~/C/unixsocket/client.c
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
// https://systemprogrammingatntu.github.io/mp2/unix_socket.html
|
||||||
|
|
||||||
|
#define SOCKET_NAME "/tmp/resol.sock"
|
||||||
|
#define BUFFER_SIZE 12
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
struct sockaddr_un addr;
|
||||||
|
int i;
|
||||||
|
int ret;
|
||||||
|
int data_socket;
|
||||||
|
char buffer[BUFFER_SIZE];
|
||||||
|
|
||||||
|
/* Create local socket. */
|
||||||
|
data_socket = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||||
|
if (data_socket == -1) {
|
||||||
|
perror("socket");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For portability clear the whole structure, since some
|
||||||
|
* implementations have additional (nonstandard) fields in
|
||||||
|
* the structure.
|
||||||
|
*/
|
||||||
|
memset(&addr, 0, sizeof(struct sockaddr_un));
|
||||||
|
|
||||||
|
/* Connect socket to socket address */
|
||||||
|
addr.sun_family = AF_UNIX;
|
||||||
|
strncpy(addr.sun_path, SOCKET_NAME, sizeof(addr.sun_path) - 1);
|
||||||
|
|
||||||
|
ret = connect (data_socket, (const struct sockaddr *) &addr,
|
||||||
|
sizeof(struct sockaddr_un));
|
||||||
|
if (ret == -1) {
|
||||||
|
fprintf(stderr, "The server is down.\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Send arguments. */
|
||||||
|
for (i = 1; i < argc; ++i) {
|
||||||
|
ret = write(data_socket, argv[i], strlen(argv[i]) + 1);
|
||||||
|
if (ret == -1) {
|
||||||
|
perror("write");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Request result. */
|
||||||
|
strcpy (buffer, "END");
|
||||||
|
ret = write(data_socket, buffer, strlen(buffer) + 1);
|
||||||
|
if (ret == -1) {
|
||||||
|
perror("write");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Receive result. */
|
||||||
|
ret = read(data_socket, buffer, BUFFER_SIZE);
|
||||||
|
if (ret == -1) {
|
||||||
|
perror("read");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure buffer is 0-terminated. */
|
||||||
|
buffer[BUFFER_SIZE - 1] = 0;
|
||||||
|
|
||||||
|
printf("Result = %s\n", buffer);
|
||||||
|
|
||||||
|
/* Close socket. */
|
||||||
|
close(data_socket);
|
||||||
|
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
BIN
~/C/unixsocket/server
Executable file
BIN
~/C/unixsocket/server
Executable file
Binary file not shown.
123
~/C/unixsocket/server.c
Normal file
123
~/C/unixsocket/server.c
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
// https://systemprogrammingatntu.github.io/mp2/unix_socket.html
|
||||||
|
|
||||||
|
#define SOCKET_NAME "/tmp/resol.sock"
|
||||||
|
#define BUFFER_SIZE 12
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
struct sockaddr_un addr;
|
||||||
|
int down_flag = 0;
|
||||||
|
int ret;
|
||||||
|
int listen_socket;
|
||||||
|
int data_socket;
|
||||||
|
int result;
|
||||||
|
char buffer[BUFFER_SIZE];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* In case the program exited inadvertently on the last run,
|
||||||
|
* remove the socket.
|
||||||
|
*/
|
||||||
|
unlink(SOCKET_NAME);
|
||||||
|
|
||||||
|
/* Create local socket. */
|
||||||
|
listen_socket = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||||
|
if (listen_socket == -1) {
|
||||||
|
perror("socket");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For portability clear the whole structure, since some
|
||||||
|
* implementations have additional (nonstandard) fields in
|
||||||
|
* the structure.
|
||||||
|
*/
|
||||||
|
memset(&addr, 0, sizeof(struct sockaddr_un));
|
||||||
|
|
||||||
|
/* Bind socket to socket name. */
|
||||||
|
addr.sun_family = AF_UNIX;
|
||||||
|
strncpy(addr.sun_path, SOCKET_NAME, sizeof(addr.sun_path) - 1);
|
||||||
|
|
||||||
|
ret = bind(listen_socket, (const struct sockaddr *) &addr,
|
||||||
|
sizeof(struct sockaddr_un));
|
||||||
|
if (ret == -1) {
|
||||||
|
perror("bind");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Prepare for accepting connections. The backlog size is set
|
||||||
|
* to 20. So while one request is being processed other requests
|
||||||
|
* can be waiting.
|
||||||
|
*/
|
||||||
|
ret = listen(listen_socket, 20);
|
||||||
|
if (ret == -1) {
|
||||||
|
perror("listen");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This is the main loop for handling connections. */
|
||||||
|
for (;;) {
|
||||||
|
/* Wait for incoming connection. */
|
||||||
|
data_socket = accept(listen_socket, NULL, NULL);
|
||||||
|
if (data_socket == -1) {
|
||||||
|
perror("accept");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
result = 0;
|
||||||
|
for(;;) {
|
||||||
|
/* Wait for next data packet. */
|
||||||
|
ret = read(data_socket, buffer, BUFFER_SIZE);
|
||||||
|
if (ret == -1) {
|
||||||
|
perror("read");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure buffer is 0-terminated. */
|
||||||
|
buffer[BUFFER_SIZE - 1] = 0;
|
||||||
|
|
||||||
|
/* Handle commands. */
|
||||||
|
if (!strncmp(buffer, "DOWN", BUFFER_SIZE)) {
|
||||||
|
down_flag = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strncmp(buffer, "END", BUFFER_SIZE)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add received summand. */
|
||||||
|
result += atoi(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Send result. */
|
||||||
|
sprintf(buffer, "%d", result);
|
||||||
|
ret = write(data_socket, buffer, BUFFER_SIZE);
|
||||||
|
|
||||||
|
if (ret == -1) {
|
||||||
|
perror("write");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close socket. */
|
||||||
|
close(data_socket);
|
||||||
|
|
||||||
|
/* Quit on DOWN command. */
|
||||||
|
if (down_flag) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
close(listen_socket);
|
||||||
|
|
||||||
|
/* Unlink the socket. */
|
||||||
|
unlink(SOCKET_NAME);
|
||||||
|
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
28
~/Crystal/UNIXSockets/by_faustinoaq/client.cr
Normal file
28
~/Crystal/UNIXSockets/by_faustinoaq/client.cr
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
require "socket"
|
||||||
|
|
||||||
|
client = UNIXSocket.new("/tmp/myapp.sock")
|
||||||
|
|
||||||
|
Signal::INT.trap {
|
||||||
|
client.puts "quit"
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
print "name: "
|
||||||
|
name = gets.to_s
|
||||||
|
|
||||||
|
spawn {
|
||||||
|
loop {
|
||||||
|
msg = client.gets
|
||||||
|
if msg
|
||||||
|
puts msg
|
||||||
|
else
|
||||||
|
puts "server closed"
|
||||||
|
exit
|
||||||
|
end
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
loop {
|
||||||
|
msg = gets.to_s
|
||||||
|
client.puts "#{name}: #{msg}"
|
||||||
|
}
|
1
~/Crystal/UNIXSockets/by_faustinoaq/link.txt
Normal file
1
~/Crystal/UNIXSockets/by_faustinoaq/link.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
https://github.com/crystal-lang/crystal/issues/4277#issuecomment-294009173
|
38
~/Crystal/UNIXSockets/by_faustinoaq/server.cr
Normal file
38
~/Crystal/UNIXSockets/by_faustinoaq/server.cr
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
require "socket"
|
||||||
|
|
||||||
|
server = UNIXServer.new("/tmp/myapp.sock")
|
||||||
|
CLIENTS = [] of UNIXSocket
|
||||||
|
|
||||||
|
Signal::INT.trap {
|
||||||
|
puts "closing server..."
|
||||||
|
server.close
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
def on_message(client)
|
||||||
|
loop {
|
||||||
|
msg = client.gets
|
||||||
|
if msg == "quit"
|
||||||
|
puts "deleting client..."
|
||||||
|
CLIENTS.delete client
|
||||||
|
pp CLIENTS.size
|
||||||
|
break
|
||||||
|
else
|
||||||
|
yield msg
|
||||||
|
end
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
loop {
|
||||||
|
puts "waiting for client on /tmp/myapp.sock"
|
||||||
|
new_client = server.accept
|
||||||
|
spawn {
|
||||||
|
on_message(new_client) { |msg|
|
||||||
|
CLIENTS.each { |client|
|
||||||
|
client.puts msg unless client == new_client
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CLIENTS << new_client
|
||||||
|
pp CLIENTS.size
|
||||||
|
}
|
24
~/Crystal/UNIXSockets/client.cr
Normal file
24
~/Crystal/UNIXSockets/client.cr
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
require "socket"
|
||||||
|
|
||||||
|
# connect to socket
|
||||||
|
sock = UNIXSocket.new("/tmp/myapp.sock")
|
||||||
|
|
||||||
|
loop do
|
||||||
|
print "Enter command [help, start, run]: "
|
||||||
|
|
||||||
|
# get string from terminal input
|
||||||
|
string = gets.not_nil!.to_s
|
||||||
|
|
||||||
|
if string == "q"
|
||||||
|
break
|
||||||
|
end
|
||||||
|
|
||||||
|
# send string to server
|
||||||
|
sock.puts "#{string}\n"
|
||||||
|
|
||||||
|
# get response from server & print
|
||||||
|
response = sock.gets
|
||||||
|
puts response
|
||||||
|
end
|
||||||
|
|
||||||
|
sock.close
|
46
~/Crystal/UNIXSockets/server.cr
Normal file
46
~/Crystal/UNIXSockets/server.cr
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
require "socket"
|
||||||
|
require "file_utils"
|
||||||
|
|
||||||
|
SOCKET = "/tmp/myapp.sock"
|
||||||
|
|
||||||
|
begin
|
||||||
|
FileUtils.rm(SOCKET)
|
||||||
|
rescue e : File::NotFoundError
|
||||||
|
end
|
||||||
|
|
||||||
|
server = UNIXServer.new(SOCKET)
|
||||||
|
CLIENTS = [] of UNIXSocket
|
||||||
|
|
||||||
|
Signal::INT.trap do
|
||||||
|
puts "Closing server..."
|
||||||
|
server.close(delete = true)
|
||||||
|
|
||||||
|
exit
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_client(client)
|
||||||
|
loop do
|
||||||
|
message = client.gets
|
||||||
|
|
||||||
|
p! client
|
||||||
|
|
||||||
|
if message == "start"
|
||||||
|
puts "::request START command::"
|
||||||
|
client.puts "Hello :)"
|
||||||
|
elsif message == "help"
|
||||||
|
puts "::request HELP command::"
|
||||||
|
client.puts "This example ECHO unix server!"
|
||||||
|
elsif message == "run"
|
||||||
|
puts "::request RUN command::"
|
||||||
|
client.puts "Ready, Set, GO!"
|
||||||
|
else
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
puts "Listen..."
|
||||||
|
|
||||||
|
while client = server.accept
|
||||||
|
spawn handle_client(client)
|
||||||
|
end
|
3
~/HTML/update-css.html
Normal file
3
~/HTML/update-css.html
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<script>
|
||||||
|
document.write("<link type='text/css' href='../ui/css/ui.css?version=" + new Date().getTime() + "' rel='stylesheet' />");
|
||||||
|
</script>
|
Loading…
Reference in New Issue
Block a user