Last active
May 2, 2017 15:25
-
-
Save blrB/dfc66e4afa12b4771e3c2b6e18efeed6 to your computer and use it in GitHub Desktop.
TCP Echo Server-Client with random sleep and log
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <string.h> | |
#include <sys/socket.h> | |
#include <arpa/inet.h> | |
#include <unistd.h> | |
#include <stdlib.h> | |
#include <time.h> | |
#include <sys/wait.h> | |
int PORT; | |
char *ADDR; | |
int number_client; | |
char *string_for_server; | |
int create_client(); | |
int main(int argc , char *argv[]) | |
{ | |
if (argc != 4) { | |
printf("Not correct argument\n"); | |
exit(1); | |
} | |
sscanf(argv[1],"%d",&PORT); | |
ADDR = strdup(argv[2]); | |
string_for_server = strdup(argv[3]); | |
create_client(); | |
} | |
int create_client() | |
{ | |
char message[1000]; | |
strcpy(message, string_for_server); | |
srand(getpid()); | |
int sock; | |
struct sockaddr_in server; | |
char server_reply[1000]; | |
//Create socket | |
sock = socket(AF_INET , SOCK_STREAM , 0); | |
if (sock == -1){ | |
printf("Could not create socket"); | |
} | |
server.sin_addr.s_addr = inet_addr(ADDR); | |
server.sin_family = AF_INET; | |
server.sin_port = htons(PORT); | |
//Connect to remote server | |
if (connect(sock , (struct sockaddr *)&server , sizeof(server)) < 0){ | |
perror("connect failed. Error"); | |
return 1; | |
} | |
puts("Connected"); | |
int time_sleep = (rand() % 9) + 2; | |
sleep (time_sleep); | |
if( send(sock , message , strlen(message) , 0) < 0){ | |
puts("Send failed"); | |
return 1; | |
} | |
if( recv(sock , server_reply , 1000 , 0) < 0){ | |
puts("recv failed"); | |
return 1; | |
} | |
puts(server_reply); | |
time_sleep = (rand() % 9) + 2; | |
sleep (time_sleep); | |
close(sock); | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <string.h> | |
#include <stdlib.h> | |
#include <sys/socket.h> | |
#include <arpa/inet.h> | |
#include <unistd.h> | |
#include <pthread.h> | |
#include <signal.h> | |
int index_buffer; | |
char **string_buffer; | |
int PORT; | |
int SIZE_BUFFER; | |
char *FILE_PATH; | |
pthread_mutex_t lock; | |
struct readThreadParams { | |
char* clnt_name; | |
int *new_sock; | |
}; | |
void *connection_handler(void *); | |
void *client_idle(void *); | |
void sighandler(int signum){ | |
FILE *fl; | |
if ((fl = fopen(FILE_PATH, "w")) == NULL){ | |
printf("Error create file"); | |
exit(-1); | |
} | |
for(int index = 0; index < index_buffer; index++){ | |
fprintf(fl, "%s\n", string_buffer[index]); | |
free(string_buffer[index]); | |
} | |
free(string_buffer); | |
fclose(fl); | |
printf("%s\n", FILE_PATH); | |
exit(0); | |
} | |
int main(int argc , char *argv[]) | |
{ | |
if (argc != 4) { | |
printf("Not correct argument\n"); | |
exit(1); | |
} | |
sscanf(argv[1],"%d",&PORT); | |
sscanf(argv[2],"%d",&SIZE_BUFFER); | |
FILE_PATH = strdup(argv[3]); | |
string_buffer = (char**) malloc((SIZE_BUFFER)*sizeof(char*)); | |
index_buffer = 0; | |
signal(SIGINT, sighandler); | |
int socket_desc, client_sock , c , *new_sock; | |
struct sockaddr_in server , client; | |
//Create socket | |
socket_desc = socket(AF_INET , SOCK_STREAM , 0); | |
if (socket_desc == -1){ | |
printf("Could not create socket"); | |
return 1; | |
} | |
if (pthread_mutex_init(&lock, NULL) != 0){ | |
printf("\n mutex init failed\n"); | |
return 1; | |
} | |
server.sin_family = AF_INET; | |
server.sin_addr.s_addr = INADDR_ANY; | |
server.sin_port = htons(PORT); | |
if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0){ | |
//print the error message | |
perror("bind failed. Error"); | |
return 1; | |
} | |
listen(socket_desc , 3); | |
puts("Waiting for incoming connections..."); | |
c = sizeof(struct sockaddr_in); | |
while( (client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c)) ){ | |
char clnt_name[INET_ADDRSTRLEN]; | |
inet_ntop(AF_INET,&client.sin_addr.s_addr,clnt_name,sizeof(clnt_name)); | |
pthread_t sniffer_thread; | |
new_sock = (int*)malloc(1); | |
*new_sock = client_sock; | |
struct readThreadParams readParams; | |
readParams.clnt_name = clnt_name; | |
readParams.new_sock = new_sock; | |
if( pthread_create( &sniffer_thread , NULL , connection_handler , &readParams) < 0){ | |
perror("could not create thread"); | |
return 1; | |
} | |
} | |
if (client_sock < 0){ | |
perror("accept failed"); | |
return 1; | |
} | |
return 0; | |
} | |
void *client_idle(void *arg) | |
{ | |
pthread_t pthread_self = *(pthread_t*)arg; | |
while(1) | |
{ | |
sleep(1); | |
pthread_mutex_lock(&lock); | |
printf("[%lu]: idle\n", pthread_self); | |
string_buffer[index_buffer] = (char*)malloc(strlen("[]: idle") + 10 + 1); | |
sprintf(string_buffer[index_buffer], "[%lu]: idle", pthread_self); | |
index_buffer++; | |
pthread_mutex_unlock(&lock); | |
} | |
return 0; | |
} | |
void *connection_handler(void *context) { | |
struct readThreadParams *readParams = (struct readThreadParams *)context; | |
//Get the socket descriptor | |
int sock = *(int*)readParams->new_sock; | |
char *clntName = readParams->clnt_name; | |
int read_size; | |
char client_message[1000]; | |
pthread_t clock_idle; | |
pthread_create(&clock_idle, NULL, &client_idle, (void*)pthread_self()); | |
pthread_mutex_lock(&lock); | |
printf("[%lu]: accept new client %s\n", pthread_self(), clntName); | |
string_buffer[index_buffer] = (char*)malloc(strlen("[]: accept new client ") + 10 + strlen(clntName) + 1); | |
sprintf(string_buffer[index_buffer], "[%lu]: accept new client %s", pthread_self(), clntName); | |
index_buffer++; | |
pthread_mutex_unlock(&lock); | |
do { | |
if( (read_size = recv(sock , client_message , 1000 , 0)) > 0 ){ | |
pthread_mutex_lock(&lock); | |
printf("%s\n", client_message); | |
string_buffer[index_buffer] = (char*)malloc(strlen(client_message) + 1); | |
sprintf(string_buffer[index_buffer], "%s", client_message); | |
index_buffer++; | |
pthread_mutex_unlock(&lock); | |
write(sock , client_message , strlen(client_message) + 1); | |
} | |
if(read_size == 0){ | |
pthread_mutex_lock(&lock); | |
printf("[%lu]: client %s disconnected\n", pthread_self(), clntName); | |
string_buffer[index_buffer] = (char*)malloc(strlen("[]: client disconnected") + 10 + strlen(clntName) + 1); | |
sprintf(string_buffer[index_buffer], "[%lu]: client %s disconnectedr", pthread_self(), clntName); | |
index_buffer++; | |
fflush(stdout); | |
pthread_mutex_unlock(&lock); | |
pthread_cancel(clock_idle); | |
break; | |
}else if(read_size == -1){ | |
perror("recv failed"); | |
} | |
} while (1); | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
for VARIABLE in {1..10} | |
do | |
sleep 0.1 | |
./TCPClient "5223" "127.0.0.1" "HELLO $VARIABLE" & | |
done | |
wait |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
/TCPServer 5223 1024 /tmp/test-log.log |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment