c unixsocket
This commit is contained in:
parent
39470121df
commit
c07cd75d39
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);
|
||||
}
|
Loading…
Reference in New Issue
Block a user