Apostolos Fanakis
6 years ago
5 changed files with 313 additions and 10 deletions
@ -0,0 +1,56 @@ |
|||||
|
#include "helpers.h" |
||||
|
|
||||
|
int create_socket(uint16_t port) { |
||||
|
int sock; |
||||
|
struct sockaddr_in socket_name; |
||||
|
|
||||
|
// Creates the socket
|
||||
|
sock = socket (PF_INET, SOCK_STREAM, 0); //TODO: check if PF_INET is the right one
|
||||
|
if (sock < 0) { |
||||
|
perror("Couldn't create the socket."); |
||||
|
exit(EXIT_FAILURE); |
||||
|
} |
||||
|
|
||||
|
// Gives the socket a name
|
||||
|
socket_name.sin_family = AF_INET; |
||||
|
socket_name.sin_port = htons(port); |
||||
|
socket_name.sin_addr.s_addr = htonl(INADDR_ANY); |
||||
|
|
||||
|
// Binds own address structure to socket
|
||||
|
if (bind(sock, (struct sockaddr *) &socket_name, sizeof(socket_name)) < 0) { |
||||
|
perror("Couldn't bind the address structure to the socket."); |
||||
|
exit(EXIT_FAILURE); |
||||
|
} |
||||
|
|
||||
|
return sock; |
||||
|
} |
||||
|
|
||||
|
int read_from_client(int file_des, uint16_t max_line) { |
||||
|
char buffer[max_line]; |
||||
|
int nbytes; |
||||
|
|
||||
|
nbytes = read(file_des, buffer, sizeof(buffer)); |
||||
|
if (nbytes < 0) { |
||||
|
perror("Couldn't read from client."); |
||||
|
exit(EXIT_FAILURE); |
||||
|
} else if (nbytes == 0) |
||||
|
// End-of-file
|
||||
|
return -1; |
||||
|
else { |
||||
|
fprintf(stderr, "Server: got message: `%s'\n", buffer); |
||||
|
return 0; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void init_sockaddr(struct sockaddr_in *name, const char *hostname, uint16_t port) { |
||||
|
struct hostent *hostinfo; |
||||
|
|
||||
|
name->sin_family = AF_INET; |
||||
|
name->sin_port = htons(port); |
||||
|
hostinfo = gethostbyname(hostname); |
||||
|
if (hostinfo == NULL) { |
||||
|
fprintf(stderr, "Unknown host %s.\n", hostname); |
||||
|
exit(EXIT_FAILURE); |
||||
|
} |
||||
|
name->sin_addr = *(struct in_addr *) hostinfo->h_addr_list[0]; |
||||
|
} |
@ -0,0 +1,21 @@ |
|||||
|
#ifndef HELPERS_H_ |
||||
|
#define HELPERS_H_ |
||||
|
|
||||
|
#include <stdio.h> |
||||
|
#include <errno.h> |
||||
|
#include <stdlib.h> |
||||
|
#include <unistd.h> |
||||
|
#include <sys/types.h> |
||||
|
#include <sys/socket.h> |
||||
|
#include <netinet/in.h> |
||||
|
#include <netdb.h> |
||||
|
#include <arpa/inet.h> |
||||
|
#include <sys/select.h> |
||||
|
|
||||
|
int create_socket(uint16_t port); |
||||
|
|
||||
|
int read_from_client(int file_des, uint16_t max_line); |
||||
|
|
||||
|
void init_sockaddr(struct sockaddr_in *name, const char *hostname, uint16_t port); |
||||
|
|
||||
|
#endif //HELPERS_H_
|
@ -0,0 +1,155 @@ |
|||||
|
#include "zaqar.h" |
||||
|
|
||||
|
#define MESSAGE "You got mail!!! xo xo xo" |
||||
|
|
||||
|
volatile sig_atomic_t out_flag = false; |
||||
|
|
||||
|
void write_to_server(int filedes) { |
||||
|
int nbytes; |
||||
|
|
||||
|
nbytes = write(filedes, MESSAGE, strlen(MESSAGE) + 1); |
||||
|
if (nbytes < 0) { |
||||
|
perror("write"); |
||||
|
exit(EXIT_FAILURE); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void handle_alarm(int sig) { |
||||
|
if (sig == SIGALRM) { |
||||
|
out_flag = true; |
||||
|
|
||||
|
int sock; |
||||
|
struct sockaddr_in servername; |
||||
|
|
||||
|
printf("GOT_CL1\n"); |
||||
|
|
||||
|
/* Create the socket. */ |
||||
|
sock = socket (PF_INET, SOCK_STREAM, 0); |
||||
|
if (sock < 0) { |
||||
|
perror("socket (client)"); |
||||
|
exit(EXIT_FAILURE); |
||||
|
} |
||||
|
|
||||
|
/* Connect to the server. */ |
||||
|
init_sockaddr (&servername, "10.0.88.79", PORT); |
||||
|
if (connect(sock, (struct sockaddr *) &servername, sizeof (servername))) { |
||||
|
printf("GOT_CL2\n"); |
||||
|
//perror("connect (client)");
|
||||
|
//exit(EXIT_FAILURE);
|
||||
|
} else { |
||||
|
printf("GOT_CL3\n"); |
||||
|
/* Send data to the server. */ |
||||
|
write_to_server(sock); |
||||
|
} |
||||
|
|
||||
|
//close (sock);
|
||||
|
} |
||||
|
} |
||||
|
|
||||
|
int main(void) { |
||||
|
int sock; |
||||
|
fd_set active_fd_set, read_fd_set; |
||||
|
struct sockaddr_in client_name; |
||||
|
size_t size; |
||||
|
|
||||
|
alarm(0); |
||||
|
//signal(SIGALRM, handle_alarm);
|
||||
|
|
||||
|
struct itimerval new; |
||||
|
|
||||
|
new.it_interval.tv_usec = 0; |
||||
|
new.it_interval.tv_sec = 8; |
||||
|
new.it_value.tv_usec = 0; |
||||
|
new.it_value.tv_sec = 8; |
||||
|
|
||||
|
if (setitimer (ITIMER_REAL, &new, NULL) == -1) { |
||||
|
perror("Couldn't set timer."); |
||||
|
exit(EXIT_FAILURE); |
||||
|
} |
||||
|
|
||||
|
sigset_t mask; |
||||
|
int sfd; |
||||
|
struct signalfd_siginfo fdsi; |
||||
|
|
||||
|
sigemptyset(&mask); |
||||
|
sigaddset(&mask, SIGALRM); |
||||
|
/*if (sigprocmask(SIGALRM, &mask, NULL) == -1)
|
||||
|
perror("sigprocmask");*/ |
||||
|
|
||||
|
sfd = signalfd(-1, &mask, 0); |
||||
|
if (sfd == -1) |
||||
|
perror("signalfd"); |
||||
|
|
||||
|
// Creates the socket and sets it up to accept connections
|
||||
|
sock = create_socket(PORT); |
||||
|
if (listen(sock, BACKLOG_SIZE) < 0) { |
||||
|
perror("Couldn't listen for connections on the socket."); |
||||
|
exit(EXIT_FAILURE); |
||||
|
} |
||||
|
|
||||
|
printf("GOT_SV1\n"); |
||||
|
// Initializes the set of active sockets
|
||||
|
// Clears the descriptor set
|
||||
|
FD_ZERO(&active_fd_set); |
||||
|
// Sets socket in active readset
|
||||
|
FD_SET(sock, &active_fd_set); |
||||
|
FD_SET(sfd, &active_fd_set); |
||||
|
|
||||
|
while (1) { |
||||
|
printf("GOT_SV2\n"); |
||||
|
// Shallow copies the readset
|
||||
|
read_fd_set = active_fd_set; |
||||
|
|
||||
|
// Blocks until input arrives on one or more active sockets
|
||||
|
if (select(FD_SETSIZE, &read_fd_set, NULL, NULL, NULL) < 0) { |
||||
|
if (out_flag) { |
||||
|
printf("GOT_SV2.1\n"); |
||||
|
out_flag = false; |
||||
|
continue; |
||||
|
} |
||||
|
printf("GOT_SV2.2\n"); |
||||
|
perror("Couldn't initiate synchronous I/O multiplexing."); |
||||
|
exit(EXIT_FAILURE); |
||||
|
} |
||||
|
|
||||
|
// Services all the sockets with input pending
|
||||
|
for (int i = 0; i < FD_SETSIZE; ++i) { //TODO: is this needed?
|
||||
|
if (FD_ISSET(i, &read_fd_set)) { |
||||
|
printf("GOT_SV3\n"); |
||||
|
if (i == sock) { |
||||
|
// Connection request on original socket
|
||||
|
size = sizeof(client_name); |
||||
|
int new = accept(sock, (struct sockaddr *) &client_name, &size); |
||||
|
if (new < 0) { |
||||
|
perror("Couldn't accept the connection."); |
||||
|
exit(EXIT_FAILURE); |
||||
|
} |
||||
|
|
||||
|
fprintf(stderr, "Server: connect from host %s, port %hd.\n", |
||||
|
inet_ntoa(client_name.sin_addr), ntohs(client_name.sin_port)); |
||||
|
FD_SET(new, &active_fd_set); |
||||
|
} else if (i == sfd) { |
||||
|
ssize_t s = read(sfd, &fdsi, sizeof(struct signalfd_siginfo)); |
||||
|
if (s != sizeof(struct signalfd_siginfo)) |
||||
|
perror("read"); |
||||
|
|
||||
|
if (fdsi.ssi_signo == SIGALRM) { |
||||
|
printf("Got SIGALRM\n"); |
||||
|
handle_alarm(SIGALRM); |
||||
|
} else { |
||||
|
printf("Read unexpected signal\n"); |
||||
|
} |
||||
|
} else { |
||||
|
// Data arriving on an already-connected socket
|
||||
|
if (read_from_client(i, MAXLINE) < 0) { |
||||
|
close(i); |
||||
|
FD_CLR(i, &active_fd_set); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
printf("GOT_SV4\n"); |
||||
|
} |
||||
|
|
||||
|
return 0; |
||||
|
} |
@ -0,0 +1,27 @@ |
|||||
|
#ifndef ZAQAR_H_ |
||||
|
#define ZAQAR_H_ |
||||
|
|
||||
|
#include <stdbool.h> |
||||
|
#include <signal.h> |
||||
|
#include <string.h> |
||||
|
#include <stdio.h> |
||||
|
#include <errno.h> |
||||
|
#include <stdlib.h> |
||||
|
#include <unistd.h> |
||||
|
#include <sys/types.h> |
||||
|
#include <sys/socket.h> |
||||
|
#include <netinet/in.h> |
||||
|
#include <netdb.h> |
||||
|
#include <arpa/inet.h> |
||||
|
#include <sys/select.h> |
||||
|
#include <sys/time.h> |
||||
|
|
||||
|
#include <sys/signalfd.h> |
||||
|
|
||||
|
#include "helpers.h" |
||||
|
|
||||
|
#define PORT 5000 |
||||
|
#define MAXLINE 1024 |
||||
|
#define BACKLOG_SIZE 2 |
||||
|
|
||||
|
#endif //ZAQAR_H_
|
Loading…
Reference in new issue