Finished Topic-12

This commit is contained in:
Sergiusz Warga 2021-05-30 20:25:49 +02:00
parent 9f6a42befe
commit b3318ab186
3 changed files with 206 additions and 20 deletions

View File

@ -0,0 +1,85 @@
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
void handle_arguments(int argc, char *argv[]) {
if (argc != 2) {
fprintf(stderr, "Usage: %s PORT\n", argv[0]);
exit(EXIT_FAILURE);
}
}
void send_integers(int sockfd, struct sockaddr_in * server_addr) {
int buffer = 42;
while (1) {
// int rv = sendto(sockfd, buffer.array, sizeof(buffer), 0, (const struct sockaddr *)&server_addr, sizeof(server_addr));
int rv = sendto(sockfd, &buffer, sizeof(buffer), 0, (const struct sockaddr *)&server_addr, sizeof(server_addr));
if (rv == -1) {
perror("sendto: ");
exit(EXIT_FAILURE);
}
// printf("Sent %x to the server\n", buffer.number);
sleep(10);
}
}
void run_client(int port) {
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
fprintf(stderr, "socket: ");
exit(EXIT_FAILURE);
}
struct sockaddr_in server_addr;
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;
server_addr.sin_port = htons(port);
if (connect(sockfd, (const struct sockaddr *)&server_addr, sizeof(server_addr))) {
perror("connect");
exit(EXIT_FAILURE);
}
pid_t pid;
pid = fork();
if (pid == -1) {
perror("fork: ");
exit(EXIT_FAILURE);
}
if (pid == 0) {
send_integers(sockfd, &server_addr);
}
char response[] = "DATA RECEIVED";
char buffer[100];
int rv;
while (1) {
rv = recv(sockfd, buffer, sizeof(buffer), 0);
if (rv < 0) {
fprintf(stderr, "recvfrom: ");
exit(EXIT_FAILURE);
}
if (strlen(buffer)) {
printf("From server: %s\n", buffer);
rv = send(sockfd, response, sizeof(response), 0);
if (rv == -1) {
perror("send");
exit(EXIT_FAILURE);
}
}
memset(&buffer, 0, sizeof(buffer));
}
}
int main(int argc, char *argv[]) {
handle_arguments(argc, argv);
run_client(strtol(argv[1], NULL, 10));
return 0;
}

View File

@ -4,6 +4,7 @@
#include <string.h> #include <string.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h>
void handle_arguments(int argc, char *argv[]) { void handle_arguments(int argc, char *argv[]) {
if (argc != 2) { if (argc != 2) {
@ -13,57 +14,57 @@ void handle_arguments(int argc, char *argv[]) {
} }
void run_server(int port) { void run_server(int port) {
// create a socket using Internet protocol
int sockfd = socket(AF_INET, SOCK_STREAM, 0); int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) { if (sockfd == -1) {
fprintf(stderr, "socket: "); perror("socket");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
struct sockaddr_in serv_addr, client_addr; struct sockaddr_in serv_addr, client_addr;
socklen_t client_addr_len; socklen_t client_addr_len = sizeof(client_addr);
memset(&serv_addr, 0, sizeof(serv_addr)); memset(&serv_addr, 0, sizeof(serv_addr));
memset(&client_addr, 0, sizeof(client_addr)); memset(&client_addr, 0, sizeof(client_addr));
serv_addr.sin_family = AF_INET; serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(port); serv_addr.sin_port = htons(port);
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
// bind sockfd to serv_addr
int rv = bind(sockfd, (const struct sockaddr *)&serv_addr, sizeof(serv_addr)); int rv = bind(sockfd, (const struct sockaddr *)&serv_addr, sizeof(serv_addr));
if (rv < 0) { if (rv == -1) {
fprintf(stderr, "bind: "); perror("bind");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
rv = listen(sockfd, 5); rv = listen(sockfd, 5);
if (rv < 0) { if (rv == -1) {
fprintf(stderr, "listen: "); perror("listen");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
int accfd = accept(sockfd, (struct sockaddr *)&client_addr, &client_addr_len); int accfd = accept(sockfd, (struct sockaddr *)&client_addr, &client_addr_len);
if (accfd < 0) { if (accfd == -1) {
fprintf(stderr, "accept: "); perror("accept");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
size_t buffer_size = sizeof(uint32_t);
size_t buffer_size = 100; union {
char buffer[buffer_size]; uint32_t number;
char array[buffer_size];
} buffer;
memset(&buffer, 0, buffer_size); memset(&buffer, 0, buffer_size);
while (1) { while (1) {
read(accfd, buffer, buffer_size); read(accfd, buffer.array, buffer_size);
write(accfd, buffer, buffer_size); printf("%d\n", ntohl(buffer.number));
write(accfd, buffer.array, buffer_size);
memset(&buffer, 0, buffer_size); memset(&buffer, 0, buffer_size);
} }
} }
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
// Socket
// setsockopt
// Bind
// listen()
// accept
// send/recv
handle_arguments(argc, argv); handle_arguments(argc, argv);
run_server(strtol(argv[1], NULL, 10)); run_server(strtol(argv[1], NULL, 10));

100
Topic-12/server_task_6-4.c Normal file
View File

@ -0,0 +1,100 @@
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
void handle_arguments(int argc, char *argv[]) {
if (argc != 3) {
fprintf(stderr, "Usage: %s PORT N_OF_CLIENTS\n", argv[0]);
exit(EXIT_FAILURE);
}
}
void run_child(int sockfd) {
struct sockaddr_in client_addr;
socklen_t client_addr_len = sizeof(client_addr);
memset(&client_addr, 0, sizeof(client_addr));
while (1) {
int accfd = accept(sockfd, (struct sockaddr *)&client_addr, &client_addr_len);
if (accfd == -1) {
perror("accept");
exit(EXIT_FAILURE);
}
printf("A new connection has been accepted!\n");
size_t buffer_size = sizeof(int);
int buffer;
while (read(accfd, &buffer, buffer_size)) {
printf("%d\n", buffer);
// write(accfd, buffer.array, buffer_size);
memset(&buffer, 0, buffer_size);
}
printf("A connection with the client has been closed!\n");
}
}
void run_server(int port, int n_of_clients) {
// create a socket using Internet protocol
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1) {
perror("socket");
exit(EXIT_FAILURE);
}
struct sockaddr_in serv_addr;
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(port);
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
// bind sockfd to serv_addr
int rv = bind(sockfd, (const struct sockaddr *)&serv_addr, sizeof(serv_addr));
if (rv == -1) {
perror("bind");
exit(EXIT_FAILURE);
}
// man 2 listen
// The behavior of the backlog argument on TCP sockets changed with Linux 2.2. Now it specifies the queue length for completely established sockets waiting to be accepted, instead of the number of
// incomplete connection requests. The maximum length of the queue for incomplete sockets can be set using /proc/sys/net/ipv4/tcp_max_syn_backlog. When syncookies are enabled there is no logical
// maximum length and this setting is ignored. See tcp(7) for more information.
rv = listen(sockfd, 5);
if (rv == -1) {
perror("listen");
exit(EXIT_FAILURE);
}
pid_t pid;
int status[n_of_clients];
int children_pids[n_of_clients];
for (int i = 0; i < n_of_clients; ++i) {
pid = fork();
if (pid == -1) {
perror("fork: ");
exit(EXIT_FAILURE);
}
if (pid == 0) {
printf("A new child has been spawned!\n");
run_child(sockfd);
}
}
for (int i = 0; i < n_of_clients; ++i) {
children_pids[i] = pid;
waitpid(children_pids[i], &status[i], 0);
}
}
int main(int argc, char *argv[]) {
handle_arguments(argc, argv);
run_server(strtol(argv[1], NULL, 10), strtol(argv[2], NULL, 10));
return 0;
}