Commit c416336d authored by Heiko Liermann's avatar Heiko Liermann
Browse files

- did some bugfixes at chargen and echo server

- both are independent from used protocol
- added setsock and calloc wrap
parent 9fe29c26
......@@ -105,6 +105,19 @@ int shutdown_wrapper(int fd, int how) {
return i;
}
void *calloc_wrap(size_t nmemb, size_t size) {
void *result = calloc(nmemb, size);
if (result == NULL) {
perror("calloc error");
exit(EXIT_FAILURE);
}
return result;
}
int setsockopt_wrap(int fd, int level, int optname, const void* optval, socklen_t optlen) {
if (setsockopt(fd, level, optname, optval, optlen) != 0) {
perror("error occur during setsockopt");
return -1;
}
return 0;
}
......@@ -38,5 +38,7 @@ int close_wrapper(int fd);
int shutdown_wrapper(int fd, int how);
ssize_t recvfrom_wrapper(int fd, void *buf, size_t buflen, int flags, struct sockaddr *from, socklen_t *addrlen);
ssize_t sendto_wrapper(int fd, void *buf, size_t buflen, int flags, const struct sockaddr *to, socklen_t addrlen);
void *calloc_wrap(size_t nmemb, size_t size) ;
int setsockopt_wrap(int fd, int level, int optname, const void* optval, socklen_t optlen);
#endif //NP_PRAKTIKUM2_SOCKET_H
......@@ -35,22 +35,62 @@ TCP Based Character Generator Service
#include "Socket.h"
void *thread_handler(void *args);
int main(int argc, char **argv) {
int server_fd, *client_fd, on = 1, off = 0;
pthread_t thread_id;
struct sockaddr_in6 server_addr;
//(1)The creation of the TCP socket is identical to the client code
memset(&server_addr, 0, sizeof(server_addr));
server_fd = socket_wrapper(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
server_addr.sin6_family = AF_INET6;
server_addr.sin6_addr = in6addr_any;
server_addr.sin6_port = htons(strtol(argv[1], NULL, 10));
setsockopt_wrap(server_fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(int));
//accept Ipv4 and Ipv6
setsockopt_wrap(server_fd, IPPROTO_IPV6, IPV6_V6ONLY, &off, sizeof(int));
//(2)The bind() function shall assign a local socket address to a socket identified by descriptor socket
bind_wrapper(server_fd, (const struct sockaddr *) &server_addr, (socklen_t) sizeof(server_addr));
//(3)Socket converted in listening socket, incoming connections from clients will be accepted by kernel
//server_fd = listening descriptor
//constant LISTENQ for max number of connections
listen_wrapper(server_fd, LISTENQ);
while (1) {
client_fd = (int *) calloc_wrap(1, sizeof(int));
*client_fd = accept_wrapper(server_fd, NULL, NULL);
//create thread
if (pthread_create(&thread_id, NULL, &thread_handler, client_fd) != 0) {
close_wrapper(*client_fd);
free(client_fd);
}
}
close_wrapper(server_fd);
exit(0);
}
void *thread_handler(void *args) {
uint8_t off = 0;
int client_fd = *(int*) args;
free(args);
pthread_detach(pthread_self());
// allocate memmory init it with 0
// allocate memory init it with 0
uint8_t *buf = (uint8_t *) calloc(1, 74 * sizeof(uint8_t));
if (buf == NULL)
perror("error on calloc");
while (1) {
//rfc specifies this kind of output
//rfc wants 72char in a line
//rfc specifies this kind of output
//rfc wants 72char in a line
for (uint8_t i = 0; i < 72; i++)
buf[i] = ((i + off) % (126 - 32)) + 32;
......@@ -60,50 +100,9 @@ void *thread_handler(void *args) {
if (write(client_fd, buf, sizeof(buf)) == -1)
break;
usleep(100000);
usleep(10000);
}
close_wrapper(client_fd);
free(buf);
return NULL;
}
int main(int argc, char **argv) {
int server_fd, *client_fd;
struct sockaddr_in server_addr, *client_addr;
pthread_t thread_id;
//(1)The creation of the TCP socket is identical to the client code
server_fd = socket_wrapper(AF_INET, SOCK_STREAM, 0);
memset(&server_addr, 0, sizeof(server_addr)); //socket address structure
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY); //specify the IP address allows the server to accept a client //connection on any interface,
server_addr.sin_port = htons(strtol(argv[1], NULL, 10));
bind_wrapper(server_fd, (const struct sockaddr *) &server_addr, (socklen_t) sizeof(server_addr));
//(2)The bind() function shall assign a local socket address address to a socket identified by descriptor socket
//(3)Socket converted in listening socket, incomming connections from clients will be accepted by kernel
//server_fd = listening descriptor
//constant LISTENQ for max number of connections
listen_wrapper(server_fd, LISTENQ);
struct sockaddr_in client;
int client_size = sizeof(client);
struct Args *thread_arguments;
thread_arguments = (struct Args *) malloc(sizeof(struct Args));
pthread_t thread_id;
while (1) {
client_fd = calloc(1, sizeof(int));
*client_fd = accept_wrapper(server_fd, NULL, NULL);
//cerate thread
pthread_create(&thread_id, NULL, &thread_handler, client_fd);
}
close_wrapper(server_fd);
exit(0);
}
}
\ No newline at end of file
......@@ -8,20 +8,21 @@
int
main(int argc, char **argv)
{
int server_fd, client_fd;
int server_fd, client_fd, on = 1;
struct sockaddr_in server_addr;
char buf[BUFFER_SIZE];
time_t ticks;
//(1)The creation of the TCP socket is identical to the client code
server_fd = socket_wrapper(AF_INET, SOCK_STREAM, 0);
server_fd = socket_wrapper(AF_INET, SOCK_STREAM, IPPROTO_TCP);
memset(&server_addr, 0, sizeof(server_addr)); //socket address structure
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY); //specify the IP address allows the server to accept a client //connection on any interface,
server_addr.sin_port = htons(strtol(argv[1], NULL, 10));
bind_wrapper(server_fd, (const struct sockaddr *)&server_addr, (socklen_t)sizeof(server_addr)); //(2)The bind() function shall assign a local socket address address to a socket identified by descriptor socket
setsockopt_wrap(server_fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(int));
bind_wrapper(server_fd, (const struct sockaddr *)&server_addr, (socklen_t) sizeof(server_addr)); //(2)The bind() function shall assign a local socket address address to a socket identified by descriptor socket
//(3)Socket converted in listening socket, incomming connections from clients will be accepted by kernel
//server_fd = listening descriptor
......
......@@ -25,9 +25,9 @@ int main (int argc, char **argv) {
server_addr.sin_len = sizeof(struct sockaddr_in);
#endif
setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(int));
setsockopt_wrap(server_fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(int));
//accept Ipv4 and Ipv6
setsockopt(server_fd, IPPROTO_IPV6, IPV6_V6ONLY, &off, sizeof(int));
setsockopt_wrap(server_fd, IPPROTO_IPV6, IPV6_V6ONLY, &off, sizeof(int));
//bind the socket
bind_wrapper(server_fd, (const struct sockaddr *)&server_addr, (socklen_t)sizeof(server_addr));
......@@ -36,13 +36,16 @@ int main (int argc, char **argv) {
while(1) {
// Speicher allozieren für client_fd
client_fd = calloc(1, sizeof(int));
client_fd = (int *) calloc_wrap(1, sizeof(int));
*client_fd = accept_wrapper(server_fd, NULL, NULL);
//create a thread for each client
//for each is handle_connection called
//(void *) client_fd) argument for called funktion
pthread_create(&thread_id, NULL, &thread_handler, (void *) client_fd);
if (pthread_create(&thread_id, NULL, &thread_handler, client_fd) != 0) {
close_wrapper(*client_fd);
free(client_fd);
}
}
//close fd
......@@ -53,17 +56,17 @@ int main (int argc, char **argv) {
}
void *thread_handler(void *arg) {
ssize_t read_len, send_len;
char buf[BUFFER_SIZE];
int client_fd = *(int*)arg;
free(arg);
pthread_detach(pthread_self());
do {
send_len = 0;
//read from client
read_len = recv_wrapper(client_fd, (void *) buf, sizeof(buf), 0);
send_len = 0;
//send back to client
while (send_len < read_len) {
send_len += send_wrapper(client_fd, (void *) (buf+send_len), read_len - send_len, 0);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment