Created
May 26, 2014 05:21
-
-
Save shonenada/b688638c92d7781b6f5b to your computer and use it in GitHub Desktop.
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 <unistd.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <sys/types.h> | |
#include <fcntl.h> | |
#include <signal.h> | |
#include <pthread.h> | |
#include "client_info.h" | |
#define FIFO_NAME "/tmp/server_fifo" | |
#define CLIENT_FIFO_NAME "/tmp/client_fifo" | |
#define BUFF_SIZE 200 | |
char pipe_name [BUFF_SIZE]; | |
void handler (int sig) { | |
unlink(pipe_name); | |
exit (sig); | |
} | |
void* pthread_read_fifo(void* param) { | |
int result; | |
int* client_fifo = (int*) param; | |
char buffer[BUFF_SIZE]; | |
while(1) { | |
result = read(*client_fifo, buffer, BUFF_SIZE); | |
if (result > 0) { | |
printf("%s", buffer); | |
} | |
} | |
} | |
int main (int argc, char* argv[]) { | |
int fd; | |
int res; | |
int fifo_fd, client_fifo; | |
CLIENT_INFO info; | |
char buffer[BUFF_SIZE]; | |
char username[20]; | |
pthread_t thread_id; | |
signal (SIGKILL, handler); | |
signal (SIGINT, handler); | |
signal (SIGTERM, handler); | |
if (access(FIFO_NAME, F_OK) == -1) { | |
printf("Could not open FIFO %s.\n", FIFO_NAME); | |
exit (EXIT_FAILURE); | |
} | |
fifo_fd = open(FIFO_NAME, O_WRONLY); | |
if (fifo_fd == -1) { | |
printf("Could not open %s for write access.\n", FIFO_NAME); | |
exit (EXIT_FAILURE); | |
} | |
sprintf(pipe_name, "/tmp/client_%d_fifo", getpid()); | |
res = mkfifo(pipe_name, 0777); | |
if (res != 0) { | |
printf("FIFO %s was not created! \n", pipe_name); | |
exit (EXIT_FAILURE); | |
} | |
client_fifo = open(pipe_name, O_RDONLY | O_NONBLOCK); | |
if (client_fifo == -1) { | |
printf("Could not open %s for read only access.\n", FIFO_NAME); | |
exit(EXIT_FAILURE); | |
} | |
info.pid = getpid(); | |
strcpy(info.client_fifo_name, pipe_name); | |
printf("Please input your username (less than 10 char): "); | |
scanf("%s", &username); | |
strcpy(info.username, username); | |
printf("Welcome %s!\n", info.username); | |
printf("Cammands:\n\tquit\tQuit client\n\thelp\tShow Help.\n"); | |
setbuf(stdin, NULL); | |
// 清空输入缓存先 | |
pthread_create(&thread_id, NULL, &pthread_read_fifo, &client_fifo); | |
while (1) { | |
printf(">>> Say: "); | |
fgets(buffer, BUFF_SIZE, stdin); | |
if (strcmp(buffer, "quit\n") == 0) { | |
break; | |
} | |
if (strcmp(buffer, "\n") == 0) { | |
continue; | |
} | |
strcpy(info.content, buffer); | |
write(fifo_fd, &info, sizeof(CLIENT_INFO)); | |
} | |
close(fifo_fd); | |
close(client_fifo); | |
(void) unlink(pipe_name); | |
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
#ifndef _CLIENTINFO_H | |
#define _CLIENTINFO_H | |
typedef struct { | |
// FIFO name of client | |
int pid; | |
char client_fifo_name[100]; | |
char username[20]; | |
char content[200]; | |
} CLIENT_INFO, *CLIENT_INFO_PTR; | |
#endif // _CLIENTINFO_H |
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 <unistd.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <sys/types.h> | |
#include <fcntl.h> | |
#include <signal.h> | |
#include "client_info.h" | |
#define FIFO_NAME "/tmp/server_fifo" | |
#define CLIENT_FIFO_NAME "/tmp/client_fifo" | |
void handler(int sig) { | |
unlink(FIFO_NAME); | |
exit(1); | |
} | |
int add_client(int client_pids[], int client, int total) { | |
int i; | |
for (i=0;i<total;i++) { | |
if (client_pids[i] == client) { | |
return total; | |
} | |
} | |
client_pids[total] = client; | |
total = total + 1; | |
return total; | |
} | |
void broadcast(int clients[], CLIENT_INFO info, int total) { | |
int i; | |
char pipe_name[250]; | |
char buffer[250]; | |
int client_fd; | |
sprintf(buffer, "%s say: %s", info.nickname, info.content); | |
for (i=0;i<total;i++) { | |
sprintf(pipe_name, "/tmp/client_%d_fifo", clients[i]); | |
client_fd = open(pipe_name, O_WRONLY | O_NONBLOCK); | |
write(client_fd, buffer, strlen(buffer) + 1); | |
close(client_fd); | |
} | |
} | |
int main(int argc, char * argv[]) { | |
enum actions = {"LOG", "REG", "SAY"}; | |
int i; | |
int res; | |
int fifo_fd, client_fd; | |
CLIENT_INFO info; | |
// char buffer[250]; | |
int client_pids[20]; | |
int client_total = 0; | |
signal (SIGKILL, handler); | |
signal (SIGINT, handler); | |
signal (SIGTERM, handler); | |
// create FIFO, if necessary | |
if (access(FIFO_NAME, F_OK) == -1) { | |
res = mkfifo(FIFO_NAME, 0777); | |
if (res != 0) { | |
printf("FIFO %s was not created.\n", FIFO_NAME); | |
exit(EXIT_FAILURE); | |
} | |
} | |
// open FIFO for reading | |
fifo_fd = open(FIFO_NAME, O_RDONLY); | |
if (fifo_fd == -1) { | |
printf("Could not open %s for read only access.\n", FIFO_NAME); | |
exit(EXIT_FAILURE); | |
} | |
printf("\nServer is runing!\n"); | |
while(1) { | |
res = read(fifo_fd, &info, sizeof(CLIENT_INFO)); | |
if (res != 0) { | |
client_total = add_client(client_pids, info.pid, client_total); | |
printf("%s say: %s", info.nickname, info.content); | |
broadcast(client_pids, info, client_total); | |
} | |
} | |
exit(0); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment