├── .gitignore ├── Makefile ├── README ├── client.c ├── server.c ├── thread.cpp └── win.c /.gitignore: -------------------------------------------------------------------------------- 1 | client 2 | server 3 | win 4 | daemon 5 | thread 6 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | TARGET = server client 2 | 3 | CC = gcc 4 | C++ = g++ 5 | CFLAGS = -Wall 6 | 7 | all:$(TARGET) 8 | 9 | server:server.c 10 | $(CC) $(CFLAGS) -o $@ $< 11 | 12 | client:client.c 13 | $(CC) $(CFLAGS) -o $@ $< 14 | 15 | clean: 16 | rm -rf $(TARGET) 17 | 18 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | 可用來做 client/server 範例 2 | 3 | Usage: 4 | 5 | 1. make 6 | 2. ./server 7 | 3. 開另一個新的終端機, ./client 8 | -------------------------------------------------------------------------------- /client.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | const char *NAME = "./my_sock"; 12 | #define MSG "Hello world!" 13 | #define MAX 1024 14 | const int PORT = 2010; 15 | 16 | int orig_sock; 17 | //int main() 18 | int socket_init(void) 19 | { 20 | struct sockaddr_in serv_adr; 21 | struct hostent *host; 22 | 23 | host = gethostbyname("localhost"); 24 | 25 | if ((orig_sock = socket(PF_INET, SOCK_STREAM, 0)) < 0) { 26 | perror("generate error"); 27 | return 1; 28 | } 29 | 30 | memset(&serv_adr, 0, sizeof(serv_adr)); 31 | serv_adr.sin_family = AF_INET; 32 | memcpy(&serv_adr.sin_addr, host->h_addr, host->h_length); 33 | serv_adr.sin_port = htons(PORT); 34 | 35 | if (connect(orig_sock, (struct sockaddr*)&serv_adr, 36 | sizeof(serv_adr)) < 0) { 37 | perror("connect error"); 38 | return 2; 39 | } 40 | 41 | return 0; 42 | } 43 | 44 | #define SIZE 1048576*8 45 | int main() 46 | { 47 | // char buf[MAX]; 48 | char *buf; 49 | ssize_t ret = 0; 50 | FILE *fp = fopen("a.bin", "wb");; 51 | 52 | buf = malloc(SIZE); 53 | 54 | socket_init(); 55 | 56 | buf[0] = '1'; 57 | printf("Sending a request\n"); 58 | write(orig_sock, &buf[0], 1); 59 | printf("Waiting for server...\n"); 60 | do { 61 | ret += read(orig_sock, buf+ret, SIZE - ret); 62 | } while (ret != SIZE); 63 | printf("read total: %lu bytes\n", ret); 64 | fwrite(buf, SIZE, 1, fp); 65 | 66 | buf[0] = '0'; 67 | printf("Sending end request, bye~\n"); 68 | write(orig_sock, &buf[0], 1); 69 | 70 | printf("\n"); 71 | close(orig_sock); 72 | free(buf); 73 | fclose(fp); 74 | return 0; 75 | } 76 | 77 | -------------------------------------------------------------------------------- /server.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | const char *NAME = "./my_sock"; 12 | #define MAX 1024 13 | 14 | socklen_t clnt_len; 15 | int orig_sock, new_sock; 16 | static struct sockaddr_in clnt_adr, serv_adr; 17 | const int PORT = 2010; 18 | 19 | void clean_up(int , const char*); 20 | 21 | void start_socket() 22 | { 23 | if ((orig_sock = socket(PF_INET, SOCK_STREAM, 0)) < 0) { 24 | perror("generate error"); 25 | } 26 | } 27 | 28 | void start_bind() 29 | { 30 | memset(&serv_adr, 0, sizeof(serv_adr)); 31 | serv_adr.sin_family = AF_INET; 32 | serv_adr.sin_addr.s_addr = htonl(INADDR_ANY); 33 | serv_adr.sin_port = htons(PORT); 34 | 35 | if (bind(orig_sock, (struct sockaddr *)&serv_adr, 36 | sizeof(serv_adr)) < 0) { 37 | perror("bind error"); 38 | clean_up(orig_sock, NAME); 39 | } 40 | } 41 | 42 | void start_listen() 43 | { 44 | listen(orig_sock, 5); 45 | } 46 | 47 | void start_accept() 48 | { 49 | clnt_len = sizeof(clnt_adr); 50 | if ((new_sock = accept(orig_sock, (struct sockaddr *)&clnt_adr, &clnt_len)) < 0) { 51 | perror("accept error"); 52 | clean_up(orig_sock, NAME); 53 | } 54 | } 55 | 56 | #define SIZE 1048576*8 57 | int main(int argc, char **argv) 58 | { 59 | char *clnt_buf; 60 | char recv_buf[MAX]; 61 | ssize_t ret; 62 | 63 | clnt_buf = malloc(SIZE); 64 | memset(clnt_buf, 'A', SIZE); 65 | 66 | start_socket(); 67 | start_bind(); 68 | start_listen(); 69 | start_accept(); 70 | 71 | for (;;) { 72 | read(new_sock, &recv_buf, 1); 73 | while (recv_buf[0] == '1') { 74 | ret = 0; 75 | do { 76 | ret += write(new_sock, clnt_buf, SIZE - ret); 77 | printf("write %lu bytes\n", ret); 78 | } while (ret != SIZE); 79 | read(new_sock, &recv_buf, 1); 80 | } 81 | printf("Client ask me to close\n"); 82 | close(new_sock); 83 | printf("Wait for another connection\n"); 84 | start_accept(); 85 | } 86 | 87 | close(new_sock); 88 | free(clnt_buf); 89 | clean_up(orig_sock, NAME); 90 | return 0; 91 | } 92 | 93 | void clean_up(int sd, const char *the_file) 94 | { 95 | close(sd); 96 | unlink(the_file); 97 | } 98 | 99 | -------------------------------------------------------------------------------- /thread.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | class Parent { 7 | public: 8 | Parent() : p_status(&status), thread_enable(0) {} 9 | void start_server() { 10 | int ret = pthread_create(&tid, NULL, thread_func, NULL); 11 | if (ret == 0) 12 | printf("Start a thread\n"); 13 | else 14 | printf("Can't start a thread: %s\n", strerror(ret)); 15 | } 16 | static void *thread_func(void *data) { 17 | while (state == 1) { 18 | printf("In thread function, %d\n", count++); 19 | sleep(1); 20 | } 21 | return NULL; 22 | } 23 | void stop() { 24 | state = 0; 25 | if (pthread_join(tid, (void**)p_status) == 0) 26 | printf("End a thread\n"); 27 | else 28 | printf("Can't end a thread: %d\n", status); 29 | } 30 | private: 31 | static int state, count; 32 | pthread_t tid; 33 | int status, *p_status; 34 | int thread_enable; 35 | }; 36 | 37 | int Parent::state = 1; 38 | int Parent::count = 0; 39 | 40 | class A : public Parent { 41 | public: 42 | void start() { 43 | Parent::start_server(); 44 | } 45 | void stop() { 46 | Parent::stop(); 47 | } 48 | }; 49 | 50 | int main() 51 | { 52 | A a; 53 | a.start(); 54 | sleep(3); 55 | a.stop(); 56 | return 0; 57 | } 58 | 59 | -------------------------------------------------------------------------------- /win.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define ENTER 10 5 | #define ESCAPE 27 6 | void init_curses() 7 | { 8 | initscr(); 9 | start_color(); 10 | init_pair(1,COLOR_WHITE,COLOR_BLUE); 11 | init_pair(2,COLOR_BLUE,COLOR_WHITE); 12 | init_pair(3,COLOR_RED,COLOR_WHITE); 13 | curs_set(0); 14 | noecho(); 15 | keypad(stdscr,TRUE); 16 | } 17 | void draw_menubar(WINDOW *menubar) 18 | { 19 | wbkgd(menubar,COLOR_PAIR(2)); 20 | waddstr(menubar,"Menu1"); 21 | wattron(menubar,COLOR_PAIR(3)); 22 | waddstr(menubar,"(F1)"); 23 | wattroff(menubar,COLOR_PAIR(3)); 24 | wmove(menubar,0,20); 25 | waddstr(menubar,"Menu2"); 26 | wattron(menubar,COLOR_PAIR(3)); 27 | waddstr(menubar,"(F2)"); 28 | wattroff(menubar,COLOR_PAIR(3)); 29 | } 30 | WINDOW **draw_menu(int start_col) 31 | { 32 | int i; 33 | WINDOW **items; 34 | items=(WINDOW **)malloc(9*sizeof(WINDOW *)); 35 | 36 | items[0]=newwin(10,19,1,start_col); 37 | wbkgd(items[0],COLOR_PAIR(2)); 38 | box(items[0],ACS_VLINE,ACS_HLINE); 39 | items[1]=subwin(items[0],1,17,2,start_col+1); 40 | items[2]=subwin(items[0],1,17,3,start_col+1); 41 | items[3]=subwin(items[0],1,17,4,start_col+1); 42 | items[4]=subwin(items[0],1,17,5,start_col+1); 43 | items[5]=subwin(items[0],1,17,6,start_col+1); 44 | items[6]=subwin(items[0],1,17,7,start_col+1); 45 | items[7]=subwin(items[0],1,17,8,start_col+1); 46 | items[8]=subwin(items[0],1,17,9,start_col+1); 47 | for (i=1;i<9;i++) 48 | wprintw(items[i],"Item%d",i); 49 | wbkgd(items[1],COLOR_PAIR(1)); 50 | wrefresh(items[0]); 51 | return items; 52 | } 53 | void delete_menu(WINDOW **items,int count) 54 | { 55 | int i; 56 | for (i=0;i