Skip to content

Instantly share code, notes, and snippets.

@vectorijk
Created February 2, 2017 12:00
Show Gist options
  • Save vectorijk/7cf7013a26d78107deb3515301f2b071 to your computer and use it in GitHub Desktop.
Save vectorijk/7cf7013a26d78107deb3515301f2b071 to your computer and use it in GitHub Desktop.
platform9 internship

Build

Under current directory, run make

Run

Server:

In one terminal, ./server to start server

Client:

For every client, we need to use one separate terminal to run it.

For example,

Client 1: In terminal 1, ./client localhost to start client 1. Client 1: In terminal 2, ./client localhost to start client 2. Client ...

Max number of client the server accept is 20.

We can type anything message (length not exceed 1024 characters) to each client. The message will be broadcasted to all client.

#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <string.h>
#include <sys/select.h>
#include <sys/time.h>
#include <unistd.h>
#include <netdb.h>
int main(int argc, char **argv) {
fd_set read_fds;
struct sockaddr_in server;
struct hostent *hp;
int sock;
char send_msg[1024];
char received_msg[1024];
int msg;
int size_of_sock = sizeof(struct sockaddr_in);
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
perror("Failed to create socket");
exit(1);
}
printf("Socket created!\n");
bzero((char *)&server, sizeof(struct sockaddr_in));
server.sin_family = AF_INET;
hp = gethostbyname(argv[1]);
if (hp == 0) {
perror("Gethostbyname failed");
exit(1);
}
memcpy(&server.sin_addr, hp->h_addr, hp->h_length);
//Remote port manually set to 23333. Changeable.
server.sin_port = htons(23333);
if (connect(sock, (struct sockaddr *)&server, size_of_sock) < 0) {
perror("Connection failed");
close(sock);
exit(1);
}
printf("Server connection established.\r\n\n");
printf("Client COMMANDS:\r\n");
printf("/TEST\tServer test\r\n");
printf("/SHOW\tList all clients\r\n");
printf("/QUIT\tDisconnect from server\r\n");
while (1) {
int fd_max = STDIN_FILENO;
FD_ZERO(&read_fds);
FD_SET(STDIN_FILENO, &read_fds);
FD_SET(sock, &read_fds);
if (sock > fd_max) fd_max = sock;
if (select(fd_max + 1, &read_fds, NULL, NULL, NULL) < 0) {
perror("Select failed");
exit(1);
}
if (FD_ISSET(sock, &read_fds)) {
msg = recv(sock, received_msg, 1024, 0);
if (msg < 0) {
perror("Receive failed");
close(sock);
exit(1);
}
if (msg == 0) {
printf("Session terminated\n");
break;
}
received_msg[msg] = '\0';
printf("Message: %s\n", received_msg);
}
if (FD_ISSET(STDIN_FILENO, &read_fds)) {
if (fgets(send_msg, 1024, stdin)) {
if (send(sock, send_msg, strlen(send_msg), 0) < 0) {
perror("Send failed");
close(sock);
exit(1);
}
}
}
}
close(sock);
return 0;
}
CC = gcc
THREAD = -pthread
build:
$(CC) $(THREAD) -o client client.c
$(CC) $(THREAD) -o server server.c
clean:
rm client
rm server
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <string.h>
#include <pthread.h>
#include <stdbool.h>
#define MAX_CLIENTS 20
#define MAX_DATA 1024
static unsigned int count = 0;
static int client_id = 0;
char user_list[MAX_DATA];
typedef struct {
struct sockaddr_in addr; //client address
int sockfd; //file descriptor
int index; //mark client by a integer number
char name[20]; //name of the client
} client_info;
client_info *client_list[MAX_CLIENTS];
void *client_connection_handler(void *socket);
void add_client(client_info *new_client); //Connect/Add a new client to server
void remove_client(int target); //Remove a client
void message_all(char *message_to_send); //Send message to all clients
void broadcast(char *message_to_send,
int index); //Send message to all but self
void echo(const char *message_to_send,
int sending_sockfd); //Send message to incoming sender
void new_message(char *message); //Send new message
void list_all_user(int sockfd);
int main(int argc, char **argv) {
int sock, new;
struct sockaddr_in server, client;
int sockaddr_len = sizeof(struct sockaddr_in);
pthread_t new_thread;
int data_len;
char data[MAX_DATA];
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == -1) {
printf("the value of the socekt is%d\n ", sock);
perror("socket: ");
exit(-1);
}
printf("Socket is successfully created\n");
bzero((char *)&server, sizeof(server));
server.sin_family = AF_INET;
server.sin_port = htons(23333);
server.sin_addr.s_addr = INADDR_ANY;
if (bind(sock, (struct sockaddr *)&server, sockaddr_len) < 0) {
perror("Bind failed");
exit(1);
}
printf("Binding was successfull\n");
if (listen(sock, MAX_CLIENTS) < 0) {
perror("Listen failed");
exit(1);
}
while (1) {
new = accept(sock, (struct sockaddr *)&client, &sockaddr_len);
if (new < 0) {
perror("Accept failed ");
exit(1);
}
printf("New client connected from port %d\n", ntohs(client.sin_port));
client_info *new_client = (client_info *)malloc(sizeof(client_info));
new_client->addr = client;
new_client->sockfd = new;
new_client->index = client_id++;
sprintf(new_client->name, "Client %d", new_client->index);
add_client(new_client);
if (pthread_create(&new_thread, NULL, &client_connection_handler,
(void *)new_client) < 0) {
perror("Thread failed to create");
}
}
return 0;
}
//Handle connection from clients
void *client_connection_handler(void *socket) {
if (count >= MAX_CLIENTS) {
printf("MAX number of clients reached\n");
return;
}
count++;
char mes_in[MAX_DATA];
char mes_out[MAX_DATA];
int data_size;
client_info *client = (client_info *)socket;
int client_index = client->index;
printf("Data received. ");
strcpy(mes_out, client->name);
strcat(mes_out, " joined.\n");
broadcast(mes_out, client_index); //if new client registered, broadcast to all clients
data_size = 1;
while (data_size) {
data_size = recv(client->sockfd, mes_in, MAX_DATA, 0);
mes_in[data_size] = '\0';
mes_out[0] = '\0';
printf("Message: %s\n", mes_in);
if (data_size) {
new_message(mes_in);
if (!strlen(mes_in)) {
continue;
}
if (mes_in[0] == '/') {
char *command, *param;
command = strtok(mes_in, " ");
printf("User command received: %s\n", command);
if (strcmp(command, "/QUIT") == 0) {
break;
} else if (!strcmp(command, "/TEST")) {
echo("\nConnected!.\r\n", client->sockfd);
} else if (!strcmp(command,"/SHOW")) {
sprintf(mes_out, "\nTotal number of client(s): %d\r\n", count);
echo(mes_out, client->sockfd);
list_all_user(client->sockfd);
} else {
echo("Unknown command\r\n", client->sockfd);
}
} else {
sprintf(mes_out, "[%s] %s\r\n", client->name, mes_in);
message_all(mes_in);
}
}
}
printf("Client disconnected\n");
close(client->sockfd);
sprintf(mes_out, "Index %d %s has quit\r\n", client->index, client->name);
message_all(mes_out);
//Delete client from queue and yeild thread
remove_client(client->index);
free(client);
count--;
pthread_detach(pthread_self());
}
void add_client(client_info *new_client) {
int i;
printf("Creating new client.\n");
for (i = 0; i < MAX_CLIENTS; ++i) {
if (!client_list[i]) {
client_list[i] = new_client;
printf("New client created: Client %d\n", i);
return;
}
}
}
void remove_client(int target) {
int i;
printf("Removing client.\n");
for (i = 0; i < MAX_CLIENTS; ++i) {
if (client_list[i] && client_list[i]->index == target) {
client_list[i] = NULL;
printf("Client %d has been removed\n", i);
return;
}
}
}
void message_all(char *message_to_send) {
int i;
for (i = 0; i < MAX_CLIENTS; i++) {
if (client_list[i]) {
write(client_list[i]->sockfd, message_to_send, strlen(message_to_send));
}
}
}
void broadcast(char *message_to_send, int index) {
int i;
for (i = 0; i < MAX_CLIENTS; i++) {
if (client_list[i] && client_list[i]->index != index) {
write(client_list[i]->sockfd, message_to_send, strlen(message_to_send));
}
}
}
void echo(const char *message_to_send, int sending_sockfd) {
write(sending_sockfd, message_to_send, strlen(message_to_send));
}
void new_message(char *message) {
while (*message != '\0') {
if (*message == '\r' || *message == '\n') {
*message = '\0';
}
message++;
}
}
void list_all_user(int sockfd) {
int i;
for (i = 0; i < MAX_CLIENTS; i++) {
if (client_list[i]) {
sprintf(user_list, "Index: %d, Name: %s\r\n", client_list[i]->index,
client_list[i]->name);
echo(user_list, sockfd);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment