├── ch14
├── news.txt
├── news_receiver_brd.c
├── news_sender_brd.c
├── news_sender.c
├── news_receiver.c
└── README.md
├── ch24
├── index.html
└── webserv_linux.c
├── ch15
├── stdcpy.c
├── desto.c
├── syscpy.c
├── todes.c
├── echo_client.c
├── echo_stdserv.c
└── README.md
├── ch10
├── zombie.c
├── fork.c
├── homework
│ ├── kehou3.c
│ └── kehou5.c
├── waitpid.c
├── signal.c
├── sigaction.c
├── wait.c
├── remove_zomebie.c
├── echo_mpclient.c
├── echo_mpserv.c
└── test_server.c
├── ch13
├── writev.c
├── readv.c
├── peek_send.c
├── oob_send.c
├── peek_recv.c
└── oob_recv.c
├── ch11
├── pipe1.c
├── pipe3.c
├── pipe2.c
├── homework
│ └── kehou4.c
├── echo_storeserv.c
└── README.md
├── ch01
├── fd_seri.c
├── low_read.c
├── low_open.c
├── hello_client.c
├── hello_server.c
└── README.md
├── ch03
├── inet_aton.c
├── endian_conv.c
├── inet_addr.c
└── inet_ntoa.c
├── ch16
├── dup.c
├── sep_clnt.c
├── sep_serv.c
├── sep_serv2.c
└── README.md
├── ch18
├── thread3.c
├── thread1.c
├── thread4.c
├── thread2.c
├── semaphore.c
├── mutex.c
├── homework
│ ├── echo_client.c
│ └── echo_threadserv.c
├── chat_clnt.c
└── chat_server.c
├── ch09
├── get_buf.c
├── sock_type.c
├── set_buf.c
└── reuseadr_eserver.c
├── ch08
├── gethostbyname.c
├── gethostbyaddr.c
└── README.md
├── ch12
├── select.c
├── echo_selectserv.c
└── README.md
├── ch07
├── file_client.c
├── file_server.c
└── README.md
├── ch06
├── bound_host2.c
├── bound_host1.c
├── homework
│ ├── uchar_client.c
│ └── uchar_server.c
├── uecho_server.c
├── uecho_client.c
├── uecho_con_client.c
└── README.md
├── ch04
├── hello_client.c
├── echo_client.c
├── hello_server.c
├── echo_server.c
└── README.md
├── ch05
├── homework
│ ├── tcp_client_kehou6.c
│ ├── tcp_client_kehou5.c
│ ├── tcp_server_kehou6.c
│ └── tcp_server_kehou5.c
├── op_client.c
├── My_op_client.c
├── echo_client2.c
├── op_server.c
├── My_op_server.c
└── README.md
├── ch02
├── tcp_client.c
├── tcp_server.c
└── README.md
└── ch17
├── homework
├── chat_clnt.c
├── char_EPETserv.c
└── char_EPLTserv.c
├── echo_epollserv.c
├── echo_EPLTserv.c
├── echo_EDGEserv.c
└── echo_EPETserv.c
/ch14/news.txt:
--------------------------------------------------------------------------------
1 | 这是一段测试信息!
2 | 1
3 | 2
4 | 3
5 | 4
6 | 5
7 | !!!!!!!!!!!!!!!!!!!
8 |
--------------------------------------------------------------------------------
/ch24/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 测试
6 |
7 |
8 | 测试标题
9 | 这是一个段落
10 |
11 |
--------------------------------------------------------------------------------
/ch15/stdcpy.c:
--------------------------------------------------------------------------------
1 | #include
2 | #define BUF_SZIE 3
3 |
4 | int main(int argc, char *argv[])
5 | {
6 | FILE *fp1;
7 | FILE *fp2;
8 | char buf[BUF_SZIE];
9 |
10 | fp1 = fopen("news.txt", "r");
11 | fp2 = fopen("cpy.txt", "w");
12 |
13 | while (fgets(buf, BUF_SZIE, fp1) != NULL)
14 | fputs(buf, fp2);
15 | fclose(fp1);
16 | fclose(fp2);
17 | return 0;
18 | }
19 |
--------------------------------------------------------------------------------
/ch15/desto.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | int main()
5 | {
6 | FILE *fp;
7 | int fd = open("data.dat", O_WRONLY | O_CREAT | O_TRUNC); //创建文件并返回文件描述符
8 | if (fd == -1)
9 | {
10 | fputs("file open error", stdout);
11 | return -1;
12 | }
13 | fp = fdopen(fd, "w"); //返回 写 模式的 FILE 指针
14 | fputs("NetWork C programming \n", fp);
15 | fclose(fp);
16 | return 0;
17 | }
--------------------------------------------------------------------------------
/ch15/syscpy.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #define BUF_SIZE 3
4 |
5 | int main(int argc, char *argv[])
6 | {
7 | int fd1, fd2;
8 | int len;
9 | char buf[BUF_SIZE];
10 |
11 | fd1 = open("news.txt", O_RDONLY);
12 | fd2 = open("cpy.txt", O_WRONLY | O_CREAT | O_TRUNC);
13 |
14 | while ((len = read(fd1, buf, sizeof(buf))) > 0)
15 | write(fd2, buf, len);
16 |
17 | close(fd1);
18 | close(fd2);
19 |
20 | return 0;
21 | }
22 |
--------------------------------------------------------------------------------
/ch10/zombie.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | int main(int argc, char *argv[])
5 | {
6 | pid_t pid = fork();
7 |
8 | if (pid == 0)
9 | {
10 | puts("Hi, I am a child Process");
11 | }
12 | else
13 | {
14 | printf("Child Process ID: %d \n", pid);
15 | sleep(30);
16 | }
17 |
18 | if (pid == 0)
19 | puts("End child proess");
20 | else
21 | puts("End parent process");
22 | return 0;
23 | }
24 |
--------------------------------------------------------------------------------
/ch13/writev.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | int main(int argc, char *argv[])
5 | {
6 | struct iovec vec[2];
7 | char buf1[] = "ABCDEFG";
8 | char buf2[] = "1234567";
9 | int str_len;
10 |
11 | vec[0].iov_base = buf1;
12 | vec[0].iov_len = 3;
13 | vec[1].iov_base = buf2;
14 | vec[1].iov_len = 4;
15 |
16 | str_len = writev(1, vec, 2);
17 | puts("");
18 | printf("Write bytes: %d \n", str_len);
19 | return 0;
20 | }
21 |
--------------------------------------------------------------------------------
/ch10/fork.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | int gval = 10;
5 | int main(int argc, char *argv[])
6 | {
7 | pid_t pid;
8 | int lval = 20;
9 | gval++, lval += 5;
10 |
11 | pid = fork();
12 | if (pid == 0)
13 | gval += 2, lval += 2;
14 | else
15 | gval -= 2, lval -= 2;
16 |
17 | if (pid == 0)
18 | printf("Child Proc: [%d,%d] \n", gval, lval);
19 | else
20 | printf("Parent Proc: [%d,%d] \n", gval, lval);
21 |
22 | return 0;
23 | }
24 |
--------------------------------------------------------------------------------
/ch10/homework/kehou3.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | int main(int argc, char *argv[])
6 | {
7 | pid_t pid;
8 | int sockfd = socket(PF_INET, SOCK_STREAM, 0);
9 |
10 | pid = fork();
11 | if(pid == 0)
12 | {
13 | printf("Child sockfd: %d \n", sockfd);
14 | }
15 | else
16 | {
17 | printf("Parent sockfd: %d \n", sockfd);
18 | }
19 | return 0;
20 | }
21 |
22 | /*
23 | 结果:
24 | Parent sockfd: 3
25 | Child sockfd: 3
26 | */
--------------------------------------------------------------------------------
/ch15/todes.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | int main()
5 | {
6 | FILE *fp;
7 | int fd = open("data.dat", O_WRONLY | O_CREAT | O_TRUNC);
8 | if (fd == -1)
9 | {
10 | fputs("file open error",stdout);
11 | return -1;
12 | }
13 |
14 | printf("First file descriptor : %d \n", fd);
15 | fp = fdopen(fd, "w"); //转成 file 指针
16 | fputs("TCP/IP SOCKET PROGRAMMING \n", fp);
17 | printf("Second file descriptor: %d \n", fileno(fp)); //转回文件描述符
18 | fclose(fp);
19 | return 0;
20 | }
21 |
--------------------------------------------------------------------------------
/ch11/pipe1.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #define BUF_SIZE 30
4 |
5 | int main(int argc, char *argv[])
6 | {
7 | int fds[2];
8 | char str[] = "Who are you?";
9 | char buf[BUF_SIZE];
10 | pid_t pid;
11 | // 调用 pipe 函数创建管道,fds 数组中保存用于 I/O 的文件描述符
12 | pipe(fds);
13 | pid = fork(); //子进程将同时拥有创建管道获取的2个文件描述符,复制的并非管道,而是文件描述符
14 | if (pid == 0)
15 | {
16 | write(fds[1], str, sizeof(str));
17 | }
18 | else
19 | {
20 | read(fds[0], buf, BUF_SIZE);
21 | puts(buf);
22 | }
23 | return 0;
24 | }
25 |
--------------------------------------------------------------------------------
/ch01/fd_seri.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 |
6 | int main()
7 | {
8 | int fd1, fd2, fd3;
9 | //创建一个文件和两个套接字
10 | fd1 = socket(PF_INET, SOCK_STREAM, 0);
11 | fd2 = open("test.dat", O_CREAT | O_WRONLY | O_TRUNC);
12 | fd3 = socket(PF_INET, SOCK_DGRAM, 0);
13 | //输出之前创建的文件描述符的整数值
14 | printf("file descriptor 1: %d\n", fd1);
15 | printf("file descriptor 2: %d\n", fd2);
16 | printf("file descriptor 3: %d\n", fd3);
17 |
18 | close(fd1);
19 | close(fd2);
20 | close(fd3);
21 | return 0;
22 | }
--------------------------------------------------------------------------------
/ch03/inet_aton.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | void error_handling(char *message);
5 |
6 | int main(int argc, char *argv[])
7 | {
8 | char *addr = "127.232.124.79";
9 | struct sockaddr_in addr_inet;
10 |
11 | if (!inet_aton(addr, &addr_inet.sin_addr))
12 | error_handling("Conversion error");
13 | else
14 | printf("Network ordered integer addr: %#x \n", addr_inet.sin_addr.s_addr);
15 | return 0;
16 | }
17 |
18 | void error_handling(char *message)
19 | {
20 | fputs(message, stderr);
21 | fputc('\n', stderr);
22 | exit(1);
23 | }
--------------------------------------------------------------------------------
/ch03/endian_conv.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | int main(int argc, char *argv[])
4 | {
5 | unsigned short host_port = 0x1234;
6 | unsigned short net_port;
7 | unsigned long host_addr = 0x12345678;
8 | unsigned long net_addr;
9 |
10 | net_port = htons(host_port); //转换为网络字节序
11 | net_addr = htonl(host_addr);
12 |
13 | printf("Host ordered port: %#x \n", host_port);
14 | printf("Network ordered port: %#x \n", net_port);
15 | printf("Host ordered address: %#lx \n", host_addr);
16 | printf("Network ordered address: %#lx \n", net_addr);
17 |
18 | return 0;
19 | }
20 |
--------------------------------------------------------------------------------
/ch03/inet_addr.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | int main(int argc, char *argv[])
4 | {
5 | char *addr1 = "1.2.3.4";
6 | char *addr2 = "1.2.3.256";
7 |
8 | unsigned long conv_addr = inet_addr(addr1);
9 | if (conv_addr == INADDR_NONE)
10 | printf("Error occured! \n");
11 | else
12 | printf("Network ordered integer addr: %#lx \n", conv_addr);
13 |
14 | conv_addr = inet_addr(addr2);
15 | if (conv_addr == INADDR_NONE)
16 | printf("Error occured! \n");
17 | else
18 | printf("Network ordered integer addr: %#lx \n", conv_addr);
19 | return 0;
20 | }
21 |
--------------------------------------------------------------------------------
/ch13/readv.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #define BUF_SIZE 100
4 |
5 | int main(int argc, char *argv[])
6 | {
7 | struct iovec vec[2];
8 | char buf1[BUF_SIZE] = {
9 | 0,
10 | };
11 | char buf2[BUF_SIZE] = {
12 | 0,
13 | };
14 | int str_len;
15 |
16 | vec[0].iov_base = buf1;
17 | vec[0].iov_len = 5;
18 | vec[1].iov_base = buf2;
19 | vec[1].iov_len = BUF_SIZE;
20 |
21 | str_len = readv(0, vec, 2);
22 | printf("Read bytes: %d \n", str_len);
23 | printf("First message: %s \n", buf1);
24 | printf("Second message: %s \n", buf2);
25 | return 0;
26 | }
27 |
--------------------------------------------------------------------------------
/ch16/dup.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | int main(int argc, char *argv[])
5 | {
6 | int cfd1, cfd2;
7 | char str1[] = "Hi~ \n";
8 | char str2[] = "It's nice day~ \n";
9 |
10 | cfd1 = dup(1); //复制文件描述符 1
11 | cfd2 = dup2(cfd1, 7); //再次复制文件描述符,定为数值 7
12 |
13 | printf("fd1=%d , fd2=%d \n", cfd1, cfd2);
14 | write(cfd1, str1, sizeof(str1));
15 | write(cfd2, str2, sizeof(str2));
16 |
17 | close(cfd1);
18 | close(cfd2); //终止复制的文件描述符,但是仍有一个文件描述符
19 | write(1, str1, sizeof(str1));
20 | close(1);
21 | write(1, str2, sizeof(str2)); //无法完成输出
22 | return 0;
23 | }
24 |
--------------------------------------------------------------------------------
/ch10/waitpid.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | int main(int argc, char *argv[])
6 | {
7 | int status;
8 | pid_t pid = fork();
9 |
10 | if (pid == 0)
11 | {
12 | sleep(15); //用 sleep 推迟子进程的执行
13 | return 24;
14 | }
15 | else
16 | {
17 | //调用waitpid 传递参数 WNOHANG ,这样之前有没有终止的子进程则返回0
18 | while (!waitpid(-1, &status, WNOHANG))
19 | {
20 | sleep(3);
21 | puts("sleep 3 sec.");
22 | }
23 |
24 | if (WIFEXITED(status))
25 | printf("Child send %d \n", WEXITSTATUS(status));
26 | }
27 | return 0;
28 | }
29 |
--------------------------------------------------------------------------------
/ch03/inet_ntoa.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | int main(int argc, char *argv[])
6 | {
7 | struct sockaddr_in addr1, addr2;
8 | char *str_ptr;
9 | char str_arr[20];
10 |
11 | addr1.sin_addr.s_addr = htonl(0x1020304);
12 | addr2.sin_addr.s_addr = htonl(0x1010101);
13 | //把addr1中的结构体信息转换为字符串的IP地址形式
14 | str_ptr = inet_ntoa(addr1.sin_addr);
15 | strcpy(str_arr, str_ptr);
16 | printf("Dotted-Decimal notation1: %s \n", str_ptr);
17 |
18 | inet_ntoa(addr2.sin_addr);
19 | printf("Dotted-Decimal notation2: %s \n", str_ptr);
20 | printf("Dotted-Decimal notation3: %s \n", str_arr);
21 | return 0;
22 | }
23 |
--------------------------------------------------------------------------------
/ch10/signal.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | void timeout(int sig) //信号处理器
6 | {
7 | if (sig == SIGALRM)
8 | puts("Time out!");
9 | alarm(2); //为了每隔 2 秒重复产生 SIGALRM 信号,在信号处理器中调用 alarm 函数
10 | }
11 | void keycontrol(int sig) //信号处理器
12 | {
13 | if (sig == SIGINT)
14 | puts("CTRL+C pressed");
15 | }
16 | int main(int argc, char *argv[])
17 | {
18 | int i;
19 | signal(SIGALRM, timeout); //注册信号及相应处理器
20 | signal(SIGINT, keycontrol);
21 | alarm(2); //预约 2 秒候发生 SIGALRM 信号
22 |
23 | for (i = 0; i < 3; i++)
24 | {
25 | puts("wait...");
26 | sleep(100);
27 | }
28 | return 0;
29 | }
30 |
--------------------------------------------------------------------------------
/ch01/low_read.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #define BUF_SIZE 100
6 | void error_handling(char *message);
7 |
8 | int main()
9 | {
10 | int fd;
11 | char buf[BUF_SIZE];
12 |
13 | fd = open("data.txt", O_RDONLY);
14 | if (fd == -1)
15 | error_handling("open() error!");
16 | printf("file descriptor: %d \n", fd);
17 |
18 | if (read(fd, buf, sizeof(buf)) == -1)
19 | error_handling("read() error!");
20 | printf("file data: %s", buf);
21 | close(fd);
22 | return 0;
23 | }
24 | void error_handling(char *message)
25 | {
26 | fputs(message, stderr);
27 | fputc('\n', stderr);
28 | exit(1);
29 | }
--------------------------------------------------------------------------------
/ch10/sigaction.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | void timeout(int sig)
6 | {
7 | if (sig == SIGALRM)
8 | puts("Time out!");
9 | alarm(2);
10 | }
11 |
12 | int main(int argc, char *argv[])
13 | {
14 | int i;
15 | struct sigaction act;
16 | act.sa_handler = timeout; //保存函数指针
17 | sigemptyset(&act.sa_mask); //将 sa_mask 函数的所有位初始化成0
18 | act.sa_flags = 0; //sa_flags 同样初始化成 0
19 | sigaction(SIGALRM, &act, 0); //注册 SIGALRM 信号的处理器。
20 |
21 | alarm(2); //2 秒后发生 SIGALRM 信号
22 |
23 | for (int i = 0; i < 3; i++)
24 | {
25 | puts("wait...");
26 | sleep(100);
27 | }
28 | return 0;
29 | }
30 |
--------------------------------------------------------------------------------
/ch10/homework/kehou5.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | void ctrl_handling(int sig);
6 |
7 | int main(int argc, char *argv[])
8 | {
9 | struct sigaction act;
10 | act.sa_handler = ctrl_handling;
11 | sigemptyset(&act.sa_mask);
12 | act.sa_flags = 0;
13 | sigaction(SIGINT, &act, 0);//输入ctrl+c发出信号
14 |
15 | while(1)
16 | {
17 | sleep(1);
18 | puts("美好的一天!");
19 | }
20 | return 0;
21 | }
22 |
23 | void ctrl_handling(int sig)
24 | {
25 | char c;
26 | if(sig == SIGINT)
27 | {
28 | fputs("Do you want to exit(Y to exit)?", stdout);
29 | scanf("%c", &c);
30 | if(c == 'y' || c == 'Y')
31 | exit(1);
32 | }
33 | }
--------------------------------------------------------------------------------
/ch11/pipe3.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #define BUF_SIZE 30
4 |
5 | int main(int argc, char *argv[])
6 | {
7 | int fds1[2], fds2[2];
8 | char str1[] = "Who are you?";
9 | char str2[] = "Thank you for your message";
10 | char buf[BUF_SIZE];
11 | pid_t pid;
12 |
13 | pipe(fds1), pipe(fds2);
14 | pid = fork();
15 | if (pid == 0)
16 | {
17 | write(fds1[1], str1, sizeof(str1));
18 | read(fds2[0], buf, BUF_SIZE);
19 | printf("Child proc output: %s \n", buf);
20 | }
21 | else
22 | {
23 | read(fds1[0], buf, BUF_SIZE);
24 | printf("Parent proc output: %s \n", buf);
25 | write(fds2[1], str2, sizeof(str2));
26 | }
27 | return 0;
28 | }
29 |
--------------------------------------------------------------------------------
/ch11/pipe2.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #define BUF_SIZE 30
4 |
5 | int main(int argc, char *argv[])
6 | {
7 | int fds[2];
8 | char str1[] = "Who are you?";
9 | char str2[] = "Thank you for your message";
10 | char buf[BUF_SIZE];
11 | pid_t pid;
12 |
13 | pipe(fds);
14 | pid = fork();
15 | if (pid == 0)
16 | {
17 | write(fds[1], str1, sizeof(str1));
18 | sleep(2);
19 | read(fds[0], buf, BUF_SIZE);
20 | printf("Child proc output: %s \n", buf);
21 | }
22 | else
23 | {
24 | read(fds[0], buf, BUF_SIZE);
25 | printf("Parent proc output: %s \n", buf);
26 | write(fds[1], str2, sizeof(str2));
27 | sleep(3);
28 | }
29 | return 0;
30 | }
31 |
--------------------------------------------------------------------------------
/ch18/thread3.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | void *thread_summation(void *arg);
4 | int sum = 0;
5 |
6 | int main(int argc, char *argv[])
7 | {
8 | pthread_t id_t1, id_t2;
9 | int range1[] = {1, 5};
10 | int range2[] = {6, 10};
11 |
12 | pthread_create(&id_t1, NULL, thread_summation, (void *)range1);
13 | pthread_create(&id_t2, NULL, thread_summation, (void *)range2);
14 |
15 | pthread_join(id_t1, NULL);
16 | pthread_join(id_t2, NULL);
17 | printf("result: %d \n", sum);
18 | return 0;
19 | }
20 | void *thread_summation(void *arg)
21 | {
22 | int start = ((int *)arg)[0];
23 | int end = ((int *)arg)[1];
24 | while (start <= end)
25 | {
26 | sum += start;
27 | start++;
28 | }
29 | return NULL;
30 | }
--------------------------------------------------------------------------------
/ch18/thread1.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | void *thread_main(void *arg);
5 |
6 | int main(int argc, char *argv[])
7 | {
8 | pthread_t t_id;
9 | int thread_param = 5;
10 | // 请求创建一个线程,从 thread_main 调用开始,在单独的执行流中运行。同时传递参数
11 | if (pthread_create(&t_id, NULL, thread_main, (void *)&thread_param) != 0)
12 | {
13 | puts("pthread_create() error");
14 | return -1;
15 | }
16 | sleep(10); //延迟进程终止时间
17 | puts("end of main");
18 | return 0;
19 | }
20 | void *thread_main(void *arg) //传入的参数是 pthread_create 的第四个
21 | {
22 | int i;
23 | int cnt = *((int *)arg);
24 | for (int i = 0; i < cnt; i++)
25 | {
26 | sleep(1);
27 | puts("running thread");
28 | }
29 | return NULL;
30 | }
--------------------------------------------------------------------------------
/ch01/low_open.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | void error_handling(char *message);
6 |
7 | int main()
8 | {
9 | int fd;
10 | char buf[] = "Let's go!\n";
11 | // O_CREAT | O_WRONLY | O_TRUNC 是文件打开模式,将创建新文件,并且只能写。如存在 data.txt 文件,则清空文件中的全部数据。
12 | fd = open("data.txt", O_CREAT | O_WRONLY | O_TRUNC);
13 | if (fd == -1)
14 | error_handling("open() error!");
15 | printf("file descriptor: %d \n", fd);
16 | // 向对应 fd 中保存的文件描述符的文件传输 buf 中保存的数据。
17 | if (write(fd, buf, sizeof(buf)) == -1)
18 | error_handling("write() error!");
19 | close(fd);
20 | return 0;
21 | }
22 |
23 | void error_handling(char *message)
24 | {
25 | fputs(message, stderr);
26 | fputc('\n', stderr);
27 | exit(1);
28 | }
--------------------------------------------------------------------------------
/ch09/get_buf.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | void error_handling(char *message);
6 |
7 | int main(int argc, char *argv[])
8 | {
9 | int sock;
10 | int snd_buf, rcv_buf, state;
11 | socklen_t len;
12 |
13 | sock = socket(PF_INET, SOCK_STREAM, 0);
14 | len = sizeof(snd_buf);
15 | state = getsockopt(sock, SOL_SOCKET, SO_SNDBUF, (void *)&snd_buf, &len);
16 | if (state)
17 | error_handling("getsockopt() error");
18 |
19 | len = sizeof(rcv_buf);
20 | state = getsockopt(sock, SOL_SOCKET, SO_RCVBUF, (void *)&rcv_buf, &len);
21 | if (state)
22 | error_handling("getsockopt() error");
23 |
24 | printf("Input buffer size: %d \n", rcv_buf);
25 | printf("Output buffer size: %d \n", snd_buf);
26 |
27 | return 0;
28 | }
29 | void error_handling(char *message)
30 | {
31 | fputs(message, stderr);
32 | fputc('\n', stderr);
33 | exit(1);
34 | }
--------------------------------------------------------------------------------
/ch13/peek_send.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | void error_handling(char *message);
8 |
9 | int main(int argc, char *argv[])
10 | {
11 | int sock;
12 | struct sockaddr_in send_adr;
13 | if (argc != 3)
14 | {
15 | printf("Usage : %s \n", argv[0]);
16 | exit(1);
17 | }
18 | sock = socket(PF_INET, SOCK_STREAM, 0);
19 | memset(&send_adr, 0, sizeof(send_adr));
20 | send_adr.sin_family = AF_INET;
21 | send_adr.sin_addr.s_addr = inet_addr(argv[1]);
22 | send_adr.sin_port = htons(atoi(argv[2]));
23 |
24 | if (connect(sock, (struct sockaddr *)&send_adr, sizeof(send_adr)) == -1)
25 | error_handling("connect() error");
26 |
27 | write(sock, "123", strlen("123"));
28 | close(sock);
29 | return 0;
30 | }
31 |
32 | void error_handling(char *message)
33 | {
34 | fputs(message, stderr);
35 | fputc('\n', stderr);
36 | exit(1);
37 | }
--------------------------------------------------------------------------------
/ch10/wait.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 |
6 | int main(int argc, char *argv[])
7 | {
8 | int status;
9 | pid_t pid = fork(); //这里的子进程将在第13行通过 return 语句终止
10 |
11 | if (pid == 0)
12 | {
13 | return 3;
14 | }
15 | else
16 | {
17 | printf("Child PID: %d \n", pid);
18 | pid = fork(); //这里的子进程将在 21 行通过 exit() 函数终止
19 | if (pid == 0)
20 | {
21 | exit(7);
22 | }
23 | else
24 | {
25 | printf("Child PID: %d \n", pid);
26 | wait(&status); //之间终止的子进程相关信息将被保存到 status 中,同时相关子进程被完全销毁
27 | if (WIFEXITED(status)) //通过 WIFEXITED 来验证子进程是否正常终止。如果正常终止,则调用 WEXITSTATUS 宏输出子进程返回值
28 | printf("Child send one: %d \n", WEXITSTATUS(status));
29 |
30 | wait(&status); //因为之前创建了两个进程,所以再次调用 wait 函数和宏
31 | if (WIFEXITED(status))
32 | printf("Child send two: %d \n", WEXITSTATUS(status));
33 | sleep(30);
34 | }
35 | }
36 | return 0;
37 | }
38 |
--------------------------------------------------------------------------------
/ch18/thread4.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #define NUM_THREAD 100
6 |
7 | void *thread_inc(void *arg);
8 | void *thread_des(void *arg);
9 | long long num = 0;
10 |
11 | int main(int argc, char *argv[])
12 | {
13 | pthread_t thread_id[NUM_THREAD];
14 | int i;
15 |
16 | printf("sizeof long long: %d \n", sizeof(long long));
17 | for (i = 0; i < NUM_THREAD; i++)
18 | {
19 | if (i % 2)
20 | pthread_create(&(thread_id[i]), NULL, thread_inc, NULL);
21 | else
22 | pthread_create(&(thread_id[i]), NULL, thread_des, NULL);
23 | }
24 |
25 | for (i = 0; i < NUM_THREAD; i++)
26 | pthread_join(thread_id[i], NULL);
27 |
28 | printf("result: %lld \n", num);
29 | return 0;
30 | }
31 |
32 | void *thread_inc(void *arg)
33 | {
34 | int i;
35 | for (i = 0; i < 50000000; i++)
36 | num += 1;
37 | return NULL;
38 | }
39 | void *thread_des(void *arg)
40 | {
41 | int i;
42 | for (i = 0; i < 50000000; i++)
43 | num -= 1;
44 | return NULL;
45 | }
--------------------------------------------------------------------------------
/ch09/sock_type.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | void error_handling(char *message);
6 |
7 | int main(int argc, char *argv[])
8 | {
9 | int tcp_sock, udp_sock;
10 | int sock_type;
11 | socklen_t optlen;
12 | int state;
13 |
14 | optlen = sizeof(sock_type);
15 | tcp_sock = socket(PF_INET, SOCK_STREAM, 0);
16 | udp_sock = socket(PF_INET, SOCK_DGRAM, 0);
17 | printf("SOCK_STREAM: %d\n", SOCK_STREAM);
18 | printf("SOCK_DGRAM: %d\n", SOCK_DGRAM);
19 |
20 | state = getsockopt(tcp_sock, SOL_SOCKET, SO_TYPE, (void *)&sock_type, &optlen);
21 | if (state)
22 | error_handling("getsockopt() error");
23 | printf("Socket type one: %d \n", sock_type);
24 |
25 | state = getsockopt(udp_sock, SOL_SOCKET, SO_TYPE, (void *)&sock_type, &optlen);
26 | if (state)
27 | error_handling("getsockopt() error");
28 | printf("Socket type two: %d \n", sock_type);
29 | return 0;
30 | }
31 | void error_handling(char *message)
32 | {
33 | fputs(message, stderr);
34 | fputc('\n', stderr);
35 | exit(1);
36 | }
--------------------------------------------------------------------------------
/ch16/sep_clnt.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #define BUF_SIZE 1024
8 |
9 | int main(int argc, char *argv[])
10 | {
11 | int sock;
12 | char buf[BUF_SIZE];
13 | struct sockaddr_in serv_addr;
14 |
15 | FILE *readfp;
16 | FILE *writefp;
17 |
18 | sock = socket(PF_INET, SOCK_STREAM, 0);
19 | memset(&serv_addr, 0, sizeof(serv_addr));
20 | serv_addr.sin_family = AF_INET;
21 | serv_addr.sin_addr.s_addr = inet_addr(argv[1]);
22 | serv_addr.sin_port = htons(atoi(argv[2]));
23 |
24 | connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
25 | readfp = fdopen(sock, "r");
26 | writefp = fdopen(sock, "w");
27 |
28 | while (1)
29 | {
30 | if (fgets(buf, sizeof(buf), readfp) == NULL)
31 | break;
32 | fputs(buf, stdout);
33 | fflush(stdout);
34 | }
35 |
36 | fputs("FROM CLIENT: Thank you \n", writefp);
37 | fflush(writefp);
38 | fclose(writefp);
39 | fclose(readfp);
40 |
41 | return 0;
42 | }
43 |
--------------------------------------------------------------------------------
/ch18/thread2.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | void *thread_main(void *arg);
6 |
7 | int main(int argc, char *argv[])
8 | {
9 | pthread_t t_id;
10 | int thread_param = 5;
11 | void *thr_ret;
12 | // 请求创建一个线程,从 thread_main 调用开始,在单独的执行流中运行。同时传递参数
13 | if (pthread_create(&t_id, NULL, thread_main, (void *)&thread_param) != 0)
14 | {
15 | puts("pthread_create() error");
16 | return -1;
17 | }
18 | //main函数将等待 ID 保存在 t_id 变量中的线程终止
19 | if (pthread_join(t_id, &thr_ret) != 0)
20 | {
21 | puts("pthread_join() error");
22 | return -1;
23 | }
24 | printf("Thread return message : %s \n", (char *)thr_ret);
25 | free(thr_ret);
26 | return 0;
27 | }
28 | void *thread_main(void *arg) //传入的参数是 pthread_create 的第四个
29 | {
30 | int i;
31 | int cnt = *((int *)arg);
32 | char *msg = (char *)malloc(sizeof(char) * 50);
33 | strcpy(msg, "Hello,I'am thread~ \n");
34 | for (int i = 0; i < cnt; i++)
35 | {
36 | sleep(1);
37 | puts("running thread");
38 | }
39 | return (void *)msg; //返回值是 thread_main 函数中内部动态分配的内存空间地址值
40 | }
--------------------------------------------------------------------------------
/ch18/semaphore.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | void *read(void *arg);
6 | void *accu(void *arg);
7 | static sem_t sem_one;
8 | static sem_t sem_two;
9 | static int num;
10 |
11 | int main(int argc, char const *argv[])
12 | {
13 | pthread_t id_t1, id_t2;
14 | sem_init(&sem_one, 0, 0);
15 | sem_init(&sem_two, 0, 1);
16 |
17 | pthread_create(&id_t1, NULL, read, NULL);
18 | pthread_create(&id_t2, NULL, accu, NULL);
19 |
20 | pthread_join(id_t1, NULL);
21 | pthread_join(id_t2, NULL);
22 |
23 | sem_destroy(&sem_one);
24 | sem_destroy(&sem_two);
25 | return 0;
26 | }
27 |
28 | void *read(void *arg)
29 | {
30 | int i;
31 | for (i = 0; i < 5; i++)
32 | {
33 | fputs("Input num: ", stdout);
34 |
35 | sem_wait(&sem_two);
36 | scanf("%d", &num);
37 | sem_post(&sem_one);
38 | }
39 | return NULL;
40 | }
41 | void *accu(void *arg)
42 | {
43 | int sum = 0, i;
44 | for (i = 0; i < 5; i++)
45 | {
46 | sem_wait(&sem_one);
47 | sum += num;
48 | sem_post(&sem_two);
49 | }
50 | printf("Result: %d \n", sum);
51 | return NULL;
52 | }
--------------------------------------------------------------------------------
/ch13/oob_send.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | #define BUF_SIZE 30
9 | void error_handling(char *message);
10 |
11 | int main(int argc, char *argv[])
12 | {
13 | int sock;
14 | struct sockaddr_in recv_adr;
15 | if (argc != 3)
16 | {
17 | printf("Usage : %s \n", argv[0]);
18 | exit(1);
19 | }
20 | sock = socket(PF_INET, SOCK_STREAM, 0);
21 | memset(&recv_adr, 0, sizeof(recv_adr));
22 | recv_adr.sin_family = AF_INET;
23 | recv_adr.sin_addr.s_addr = inet_addr(argv[1]);
24 | recv_adr.sin_port = htons(atoi(argv[2]));
25 |
26 | if (connect(sock, (struct sockaddr *)&recv_adr, sizeof(recv_adr)) == -1)
27 | error_handling("connect() error");
28 |
29 | write(sock, "123", strlen("123"));
30 | send(sock, "4", strlen("4"), MSG_OOB);
31 | write(sock, "567", strlen("567"));
32 | send(sock, "890", strlen("890"), MSG_OOB);
33 | close(sock);
34 | return 0;
35 | }
36 |
37 | void error_handling(char *message)
38 | {
39 | fputs(message, stderr);
40 | fputc('\n', stderr);
41 | exit(1);
42 | }
--------------------------------------------------------------------------------
/ch08/gethostbyname.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | void error_handling(char *message);
7 |
8 | int main(int argc, char *argv[])
9 | {
10 | int i;
11 | struct hostent *host;
12 | if (argc != 2)
13 | {
14 | printf("Usage : %s \n", argv[0]);
15 | exit(1);
16 | }
17 | // 把参数传递给函数,返回结构体
18 | host = gethostbyname(argv[1]);
19 | if (!host)
20 | error_handling("gethost... error");
21 | // 输出官方域名
22 | printf("Official name: %s \n", host->h_name);
23 | // Aliases 貌似是解析的 cname 域名?
24 | for (i = 0; host->h_aliases[i]; i++)
25 | printf("Aliases %d: %s \n", i + 1, host->h_aliases[i]);
26 | //看看是不是ipv4
27 | printf("Address type: %s \n",
28 | (host->h_addrtype == AF_INET) ? "AF_INET" : "AF_INET6");
29 | // 输出ip地址信息
30 | for (i = 0; host->h_addr_list[i]; i++)
31 | printf("IP addr %d: %s \n", i + 1,
32 | inet_ntoa(*(struct in_addr *)host->h_addr_list[i]));
33 | return 0;
34 | }
35 | void error_handling(char *message)
36 | {
37 | fputs(message, stderr);
38 | fputc('\n', stderr);
39 | exit(1);
40 | }
--------------------------------------------------------------------------------
/ch11/homework/kehou4.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #define BUF_SIZE 30
5 |
6 | int main(int argc, char *argv[])
7 | {
8 | int fds1[2], fds2[2];
9 | //const char* 以"\0"作为结束符
10 | char str1[] = "Do you like cooffee?";
11 | char str2[] = "I like coffee";
12 | char str3[] = "I like long legs";
13 | char * str_arr[] = {str1, str2, str3};
14 | char buf[BUF_SIZE];
15 | pid_t pid;
16 | int i;
17 |
18 | pipe(fds1), pipe(fds2);
19 | pid = fork();
20 |
21 | if(pid == 0)
22 | {
23 | for(i = 0; i < 3; ++i)
24 | {
25 | //strlen所作的是一个计数器的工作,它从内存的某个位置(可以是字符串开头,中间某个位置,甚至是某个不确定的内存区域)开始扫描,
26 | //直到碰到第一个字符串结束符'\0'为止,然后返回计数器值(长度不包含'\0')
27 | write(fds1[1], str_arr[i], strlen(str_arr[i]) + 1);//这里长度必须加上1,将字符串结束符加进去,否则会发生消息错乱
28 | read(fds2[0], buf, BUF_SIZE);
29 | printf("子进程收到的消息:%s\n", buf);
30 | }
31 | }
32 | else
33 | {
34 | for(i = 0; i < 3; ++i)
35 | {
36 | read(fds1[0], buf, BUF_SIZE);
37 | printf("父进程收到的消息:%s\n", buf);
38 | write(fds2[1], str_arr[i], strlen(str_arr[i]) + 1);
39 | }
40 | }
41 | return 0;
42 | }
--------------------------------------------------------------------------------
/ch12/select.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #define BUF_SIZE 30
6 |
7 | int main(int argc, char *argv[])
8 | {
9 | fd_set reads, temps;
10 | int result, str_len;
11 | char buf[BUF_SIZE];
12 | struct timeval timeout;
13 |
14 | FD_ZERO(&reads); //初始化变量
15 | FD_SET(0, &reads); //将文件描述符0对应的位设置为1
16 |
17 | /*
18 | timeout.tv_sec=5;
19 | timeout.tv_usec=5000;
20 | */
21 |
22 | while (1)
23 | {
24 | temps = reads; //为了防止调用了select 函数后,位的内容改变,先提前存一下
25 | timeout.tv_sec = 5;
26 | timeout.tv_usec = 0;
27 | result = select(1, &temps, 0, 0, &timeout); //如果控制台输入数据,则返回大于0的数,没有就会超时
28 | if (result == -1)
29 | {
30 | puts("select error!");
31 | break;
32 | }
33 | else if (result == 0)
34 | {
35 | puts("Time-out!");
36 | }
37 | else
38 | {
39 | if (FD_ISSET(0, &temps)) //验证发生变化的值是否是标准输入端
40 | {
41 | str_len = read(0, buf, BUF_SIZE);
42 | buf[str_len] = 0;
43 | printf("message from console: %s", buf);
44 | }
45 | }
46 | }
47 | return 0;
48 | }
49 |
--------------------------------------------------------------------------------
/ch08/gethostbyaddr.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | void error_handling(char *message);
8 |
9 | int main(int argc, char *argv[])
10 | {
11 | int i;
12 | struct hostent *host;
13 | struct sockaddr_in addr;
14 | if (argc != 2)
15 | {
16 | printf("Usage : %s \n", argv[0]);
17 | exit(1);
18 | }
19 |
20 | memset(&addr, 0, sizeof(addr));
21 | addr.sin_addr.s_addr = inet_addr(argv[1]);
22 | host = gethostbyaddr((char *)&addr.sin_addr, 4, AF_INET);
23 | if (!host)
24 | error_handling("gethost... error");
25 |
26 | printf("Official name: %s \n", host->h_name);
27 | for (i = 0; host->h_aliases[i]; i++)
28 | printf("Aliases %d:%s \n", i + 1, host->h_aliases[i]);
29 | printf("Address type: %s \n",
30 | (host->h_addrtype == AF_INET) ? "AF_INET" : "AF_INET6");
31 |
32 | for (i = 0; host->h_addr_list[i]; i++)
33 | printf("IP addr %d: %s \n", i + 1,
34 | inet_ntoa(*(struct in_addr *)host->h_addr_list[i]));
35 |
36 | return 0;
37 | }
38 | void error_handling(char *message)
39 | {
40 | fputs(message, stderr);
41 | fputc('\n', stderr);
42 | exit(1);
43 | }
--------------------------------------------------------------------------------
/ch07/file_client.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | #define BUF_SIZE 30
9 | void error_handling(char *message);
10 |
11 | int main(int argc, char *argv[])
12 | {
13 | int sd;
14 | FILE *fp;
15 |
16 | char buf[BUF_SIZE];
17 | int read_cnt;
18 | struct sockaddr_in serv_adr;
19 |
20 | if (argc != 3)
21 | {
22 | printf("Usage : %s \n", argv[0]);
23 | exit(1);
24 | }
25 |
26 | fp = fopen("receive.cpp", "wb");
27 | sd = socket(PF_INET, SOCK_STREAM, 0);
28 |
29 | memset(&serv_adr, 0, sizeof(serv_adr));
30 | serv_adr.sin_family = AF_INET;
31 | serv_adr.sin_addr.s_addr = inet_addr(argv[1]);
32 | serv_adr.sin_port = htons(atoi(argv[2]));
33 |
34 | connect(sd, (struct sockaddr *)&serv_adr, sizeof(serv_adr));
35 |
36 | while ((read_cnt = read(sd, buf, BUF_SIZE)) != 0)
37 | fwrite((void *)buf, 1, read_cnt, fp);
38 |
39 | puts("Received file data");
40 | write(sd, "Thank you", 10);
41 | fclose(fp);
42 | close(sd);
43 | return 0;
44 | }
45 |
46 | void error_handling(char *message)
47 | {
48 | fputs(message, stderr);
49 | fputc('\n', stderr);
50 | exit(1);
51 | }
--------------------------------------------------------------------------------
/ch18/mutex.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #define NUM_THREAD 100
6 | void *thread_inc(void *arg);
7 | void *thread_des(void *arg);
8 |
9 | long long num = 0;
10 | pthread_mutex_t mutex; //保存互斥量读取值的变量
11 |
12 | int main(int argc, char *argv[])
13 | {
14 | pthread_t thread_id[NUM_THREAD];
15 | int i;
16 |
17 | pthread_mutex_init(&mutex, NULL); //创建互斥量
18 |
19 | for (i = 0; i < NUM_THREAD; i++)
20 | {
21 | if (i % 2)
22 | pthread_create(&(thread_id[i]), NULL, thread_inc, NULL);
23 | else
24 | pthread_create(&(thread_id[i]), NULL, thread_des, NULL);
25 | }
26 |
27 | for (i = 0; i < NUM_THREAD; i++)
28 | pthread_join(thread_id[i], NULL);
29 |
30 | printf("result: %lld \n", num);
31 | pthread_mutex_destroy(&mutex); //销毁互斥量
32 | return 0;
33 | }
34 |
35 | void *thread_inc(void *arg)
36 | {
37 | int i;
38 | pthread_mutex_lock(&mutex); //上锁
39 | for (i = 0; i < 50000000; i++)
40 | num += 1;
41 | pthread_mutex_unlock(&mutex); //解锁
42 | return NULL;
43 | }
44 | void *thread_des(void *arg)
45 | {
46 | int i;
47 | pthread_mutex_lock(&mutex);
48 | for (i = 0; i < 50000000; i++)
49 | num -= 1;
50 | pthread_mutex_unlock(&mutex);
51 | return NULL;
52 | }
--------------------------------------------------------------------------------
/ch14/news_receiver_brd.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | #define BUF_SIZE 30
9 | void error_handling(char *message);
10 |
11 | int main(int argc, char *argv[])
12 | {
13 | int recv_sock;
14 | int str_len;
15 | char buf[BUF_SIZE];
16 | struct sockaddr_in adr;
17 | if (argc != 2)
18 | {
19 | printf("Usage : %s \n", argv[0]);
20 | exit(1);
21 | }
22 | recv_sock = socket(PF_INET, SOCK_DGRAM, 0);
23 | memset(&adr, 0, sizeof(adr));
24 | adr.sin_family = AF_INET;
25 | adr.sin_addr.s_addr = htonl(INADDR_ANY);
26 | adr.sin_port = htons(atoi(argv[1]));
27 |
28 | if (bind(recv_sock, (struct sockaddr *)&adr, sizeof(adr)) == -1)
29 | error_handling("bind() error");
30 | while (1)
31 | {
32 | //通过 recvfrom 函数接受数据。如果不需要知道传输数据的主机地址信息,可以向recvfrom函数的第5 6参数分贝传入 NULL 0
33 | str_len = recvfrom(recv_sock, buf, BUF_SIZE - 1, 0, NULL, 0);
34 | if (str_len < 0)
35 | break;
36 | buf[str_len] = 0;
37 | fputs(buf, stdout);
38 | }
39 | close(recv_sock);
40 | return 0;
41 | }
42 |
43 | void error_handling(char *message)
44 | {
45 | fputs(message, stderr);
46 | fputc('\n', stderr);
47 | exit(1);
48 | }
--------------------------------------------------------------------------------
/ch16/sep_serv.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #define BUF_SIZE 1024
8 |
9 | int main(int argc, char *argv[])
10 | {
11 | int serv_sock, clnt_sock;
12 | FILE *readfp;
13 | FILE *writefp;
14 |
15 | struct sockaddr_in serv_adr, clnt_adr;
16 | socklen_t clnt_adr_sz;
17 | char buf[BUF_SIZE] = {
18 | 0,
19 | };
20 | serv_sock = socket(PF_INET, SOCK_STREAM, 0);
21 | memset(&serv_adr, 0, sizeof(serv_adr));
22 | serv_adr.sin_family = AF_INET;
23 | serv_adr.sin_addr.s_addr = htonl(INADDR_ANY);
24 | serv_adr.sin_port = htons(atoi(argv[1]));
25 | bind(serv_sock, (struct sockaddr *)&serv_adr, sizeof(serv_adr));
26 | listen(serv_sock, 5);
27 | clnt_adr_sz = sizeof(clnt_adr);
28 | clnt_sock = accept(serv_sock, (struct sockaddr *)&clnt_adr, &clnt_adr_sz);
29 |
30 | readfp = fdopen(clnt_sock, "r");
31 | writefp = fdopen(clnt_sock, "w");
32 |
33 | fputs("FROM SERVER: Hi~ client? \n", writefp);
34 | fputs("I love all of the world \n", writefp);
35 | fputs("You are awesome! \n", writefp);
36 | fflush(writefp);
37 |
38 | fclose(writefp);
39 | fgets(buf, sizeof(buf), readfp);
40 | fputs(buf, stdout);
41 | fclose(readfp);
42 | return 0;
43 | }
44 |
--------------------------------------------------------------------------------
/ch09/set_buf.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | void error_handling(char *message);
6 |
7 | int main(int argc, char *argv[])
8 | {
9 | int sock;
10 | int snd_buf = 1024 * 3, rcv_buf = 1024 * 3;
11 | int state;
12 | socklen_t len;
13 |
14 | sock = socket(PF_INET, SOCK_STREAM, 0);
15 | len = sizeof(snd_buf);
16 | state = setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (void *)&rcv_buf, sizeof(rcv_buf));
17 | if (state)
18 | error_handling("setsockopt() error");
19 |
20 | state = setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (void *)&snd_buf, sizeof(snd_buf));
21 | if (state)
22 | error_handling("setsockopt() error");
23 |
24 | len = sizeof(snd_buf);
25 | state = getsockopt(sock, SOL_SOCKET, SO_SNDBUF, (void *)&snd_buf, &len);
26 | if (state)
27 | error_handling("getsockopt() error");
28 |
29 | len = sizeof(rcv_buf);
30 | state = getsockopt(sock, SOL_SOCKET, SO_RCVBUF, (void *)&rcv_buf, &len);
31 | if (state)
32 | error_handling("getsockopt() error");
33 |
34 | printf("Input buffer size: %d \n", rcv_buf);
35 | printf("Output buffer size: %d \n", snd_buf);
36 |
37 | return 0;
38 | }
39 | void error_handling(char *message)
40 | {
41 | fputs(message, stderr);
42 | fputc('\n', stderr);
43 | exit(1);
44 | }
--------------------------------------------------------------------------------
/ch14/news_sender_brd.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | #define BUF_SIZE 30
9 | void error_handling(char *message);
10 |
11 | int main(int argc, char *argv[])
12 | {
13 | int send_sock;
14 | struct sockaddr_in broad_adr;
15 | FILE *fp;
16 | char buf[BUF_SIZE];
17 | int so_brd = 1;
18 | if (argc != 3)
19 | {
20 | printf("Usage : %s \n", argv[0]);
21 | exit(1);
22 | }
23 | send_sock = socket(PF_INET, SOCK_DGRAM, 0); //创建 UDP 套接字
24 | memset(&broad_adr, 0, sizeof(broad_adr));
25 | broad_adr.sin_family = AF_INET;
26 | broad_adr.sin_addr.s_addr = inet_addr(argv[1]);
27 | broad_adr.sin_port = htons(atoi(argv[2]));
28 | setsockopt(send_sock, SOL_SOCKET, SO_BROADCAST, (void *)&so_brd, sizeof(so_brd));
29 | if ((fp = fopen("news.txt", "r")) == NULL)
30 | error_handling("fopen() error");
31 |
32 | while (!feof(fp)) //如果文件没结束就返回0
33 | {
34 | fgets(buf, BUF_SIZE, fp);
35 | sendto(send_sock, buf, strlen(buf), 0, (struct sockaddr *)&broad_adr, sizeof(broad_adr));
36 | sleep(2);
37 | }
38 | fclose(fp);
39 | close(send_sock);
40 | return 0;
41 | }
42 |
43 | void error_handling(char *message)
44 | {
45 | fputs(message, stderr);
46 | fputc('\n', stderr);
47 | exit(1);
48 | }
--------------------------------------------------------------------------------
/ch10/remove_zomebie.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 |
7 | void read_childproc(int sig)
8 | {
9 | int status;
10 | pid_t id = waitpid(-1, &status, WNOHANG);
11 | if (WIFEXITED(status))
12 | {
13 | printf("Removed proc id: %d \n", id); //子进程的 pid
14 | printf("Child send: %d \n", WEXITSTATUS(status)); //子进程的返回值
15 | }
16 | }
17 |
18 | int main(int argc, char *argv[])
19 | {
20 | pid_t pid;
21 | struct sigaction act;
22 | act.sa_handler = read_childproc;
23 | sigemptyset(&act.sa_mask);
24 | act.sa_flags = 0;
25 | sigaction(SIGCHLD, &act, 0);
26 |
27 | pid = fork();
28 | if (pid == 0) //子进程执行阶段
29 | {
30 | puts("Hi I'm child process");
31 | sleep(10);
32 | return 12;
33 | }
34 | else //父进程执行阶段
35 | {
36 | printf("Child proc id: %d\n", pid);
37 | pid = fork();
38 | if (pid == 0)
39 | {
40 | puts("Hi! I'm child process");
41 | sleep(10);
42 | exit(24);
43 | }
44 | else
45 | {
46 | int i;
47 | printf("Child proc id: %d \n", pid);
48 | for (i = 0; i < 5; i++)
49 | {
50 | puts("wait");
51 | sleep(5);
52 | }
53 | }
54 | }
55 | return 0;
56 | }
57 |
--------------------------------------------------------------------------------
/ch06/bound_host2.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | #define BUF_SIZE 30
9 | void error_handling(char *message);
10 |
11 | int main(int argc, char *argv[])
12 | {
13 | int sock;
14 | char msg1[] = "Hi!";
15 | char msg2[] = "I'm another UDP host!";
16 | char msg3[] = "Nice to meet you";
17 |
18 | struct sockaddr_in your_adr;
19 | socklen_t your_adr_sz;
20 | if (argc != 3)
21 | {
22 | printf("Usage : %s \n", argv[0]);
23 | exit(1);
24 | }
25 | sock = socket(PF_INET, SOCK_DGRAM, 0);
26 | if (sock == -1)
27 | error_handling("socket() error");
28 | memset(&your_adr, 0, sizeof(your_adr));
29 | your_adr.sin_family = AF_INET;
30 | your_adr.sin_addr.s_addr = inet_addr(argv[1]);
31 | your_adr.sin_port = htons(atoi(argv[2]));
32 |
33 | sendto(sock, msg1, sizeof(msg1), 0,
34 | (struct sockaddr *)&your_adr, sizeof(your_adr));
35 | sendto(sock, msg2, sizeof(msg2), 0,
36 | (struct sockaddr *)&your_adr, sizeof(your_adr));
37 | sendto(sock, msg3, sizeof(msg3), 0,
38 | (struct sockaddr *)&your_adr, sizeof(your_adr));
39 | close(sock);
40 | return 0;
41 | }
42 |
43 | void error_handling(char *message)
44 | {
45 | fputs(message, stderr);
46 | fputc('\n', stderr);
47 | exit(1);
48 | }
49 |
--------------------------------------------------------------------------------
/ch01/hello_client.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | void error_handling(char *message);
8 |
9 | int main(int argc, char *argv[])
10 | {
11 | int sock;
12 | struct sockaddr_in serv_addr;
13 | char message[30];
14 | int str_len;
15 |
16 | if (argc != 3)
17 | {
18 | printf("Usage : %s \n", argv[0]);
19 | exit(1);
20 | }
21 | //创建套接字,此时套接字并不马上分为服务端和客户端。如果紧接着调用 bind,listen 函数,将成为服务器套接字
22 | //如果调用 connect 函数,将成为客户端套接字
23 | sock = socket(PF_INET, SOCK_STREAM, 0);
24 | if (sock == -1)
25 | error_handling("socket() error");
26 |
27 | memset(&serv_addr, 0, sizeof(serv_addr));
28 | serv_addr.sin_family = AF_INET;
29 | serv_addr.sin_addr.s_addr = inet_addr(argv[1]);
30 | serv_addr.sin_port = htons(atoi(argv[2]));
31 | //调用 connect 函数向服务器发送连接请求
32 | if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == -1)
33 | error_handling("connect() error!");
34 |
35 | str_len = read(sock, message, sizeof(message) - 1);
36 | if (str_len == -1)
37 | error_handling("read() error!");
38 |
39 | printf("Message from server : %s \n", message);
40 | close(sock);
41 | return 0;
42 | }
43 |
44 | void error_handling(char *message)
45 | {
46 | fputs(message, stderr);
47 | fputc('\n', stderr);
48 | exit(1);
49 | }
--------------------------------------------------------------------------------
/ch04/hello_client.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | void error_handling(char *message);
8 |
9 | int main(int argc, char *argv[])
10 | {
11 | int sock;
12 | struct sockaddr_in serv_addr;
13 | char message[30];
14 | int str_len;
15 |
16 | if (argc != 3)
17 | {
18 | printf("Usage : %s \n", argv[0]);
19 | exit(1);
20 | }
21 | //创建套接字,此时套接字并不马上分为服务端和客户端。如果紧接着调用 bind,listen 函数,将成为服务器套接字
22 | //如果调用 connect 函数,将成为客户端套接字
23 | sock = socket(PF_INET, SOCK_STREAM, 0);
24 | if (sock == -1)
25 | error_handling("socket() error");
26 |
27 | memset(&serv_addr, 0, sizeof(serv_addr));
28 | serv_addr.sin_family = AF_INET;
29 | serv_addr.sin_addr.s_addr = inet_addr(argv[1]);
30 | serv_addr.sin_port = htons(atoi(argv[2]));
31 | //调用 connect 函数向服务器发送连接请求
32 | if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == -1)
33 | error_handling("connect() error!");
34 |
35 | str_len = read(sock, message, sizeof(message) - 1);
36 | if (str_len == -1)
37 | error_handling("read() error!");
38 |
39 | printf("Message from server : %s \n", message);
40 | close(sock);
41 | return 0;
42 | }
43 |
44 | void error_handling(char *message)
45 | {
46 | fputs(message, stderr);
47 | fputc('\n', stderr);
48 | exit(1);
49 | }
--------------------------------------------------------------------------------
/ch05/homework/tcp_client_kehou6.c:
--------------------------------------------------------------------------------
1 | /***************************************recvsend_clnt.c***************************/
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | #define BUF_SIZE 30
10 | void error_handling(char *message);
11 |
12 | int main(int argc, char *argv[])
13 | {
14 | int sd;
15 | FILE *fp;
16 |
17 | char buf[BUF_SIZE];
18 | char file_name[BUF_SIZE];
19 | int read_cnt;
20 | struct sockaddr_in serv_adr;
21 | if(argc!=3) {
22 | printf("Usage: %s \n", argv[0]);
23 | exit(1);
24 | }
25 |
26 | //输入文件名
27 | printf("Input file name: ");
28 | scanf("%s", file_name);
29 | //打开文件名
30 | fp=fopen(file_name, "wb");
31 |
32 | //创建套接字
33 | sd=socket(PF_INET, SOCK_STREAM, 0);
34 | //初始化
35 | memset(&serv_adr, 0, sizeof(serv_adr));
36 | serv_adr.sin_family=AF_INET;
37 | serv_adr.sin_addr.s_addr=inet_addr(argv[1]);
38 | serv_adr.sin_port=htons(atoi(argv[2]));
39 |
40 | connect(sd, (struct sockaddr*)&serv_adr, sizeof(serv_adr));
41 | //写入要传输的文件
42 | write(sd, file_name, strlen(file_name)+1);
43 |
44 | while((read_cnt=read(sd, buf, BUF_SIZE))!=0)
45 | fwrite((void*)buf, 1, read_cnt, fp);
46 |
47 | fclose(fp);
48 | close(sd);
49 | return 0;
50 | }
51 |
52 | void error_handling(char *message)
53 | {
54 | fputs(message, stderr);
55 | fputc('\n', stderr);
56 | exit(1);
57 | }
58 |
59 |
60 |
--------------------------------------------------------------------------------
/ch06/bound_host1.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | #define BUF_SIZE 30
9 | void error_handling(char *message);
10 |
11 | int main(int argc, char *argv[])
12 | {
13 | int sock;
14 | char message[BUF_SIZE];
15 | struct sockaddr_in my_adr, your_adr;
16 | socklen_t adr_sz;
17 | int str_len, i;
18 | if (argc != 2)
19 | {
20 | printf("Usage : %s \n", argv[0]);
21 | exit(1);
22 | }
23 | sock = socket(PF_INET, SOCK_DGRAM, 0);
24 | if (sock == -1)
25 | error_handling("socket() error");
26 |
27 | memset(&my_adr, 0, sizeof(my_adr));
28 | my_adr.sin_family = AF_INET;
29 | my_adr.sin_addr.s_addr = htonl(INADDR_ANY);
30 | my_adr.sin_port = htons(atoi(argv[1]));
31 |
32 | if (bind(sock, (struct sockaddr *)&my_adr, sizeof(my_adr)) == -1)
33 | error_handling("bind() error");
34 |
35 | for (i = 0; i < 3; i++)
36 | {
37 | sleep(5);
38 | adr_sz = sizeof(your_adr);
39 | str_len = recvfrom(sock, message, BUF_SIZE, 0,
40 | (struct sockaddr *)&your_adr, &adr_sz);
41 | printf("Message %d: %s \n", i + 1, message);
42 | }
43 | close(sock);
44 | return 0;
45 | }
46 |
47 | void error_handling(char *message)
48 | {
49 | fputs(message, stderr);
50 | fputc('\n', stderr);
51 | exit(1);
52 | }
--------------------------------------------------------------------------------
/ch16/sep_serv2.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #define BUF_SIZE 1024
8 |
9 | int main(int argc, char *argv[])
10 | {
11 | int serv_sock, clnt_sock;
12 | FILE *readfp;
13 | FILE *writefp;
14 |
15 | struct sockaddr_in serv_adr, clnt_adr;
16 | socklen_t clnt_adr_sz;
17 | char buf[BUF_SIZE] = {
18 | 0,
19 | };
20 | serv_sock = socket(PF_INET, SOCK_STREAM, 0);
21 | memset(&serv_adr, 0, sizeof(serv_adr));
22 | serv_adr.sin_family = AF_INET;
23 | serv_adr.sin_addr.s_addr = htonl(INADDR_ANY);
24 | serv_adr.sin_port = htons(atoi(argv[1]));
25 | bind(serv_sock, (struct sockaddr *)&serv_adr, sizeof(serv_adr));
26 | listen(serv_sock, 5);
27 | clnt_adr_sz = sizeof(clnt_adr);
28 | clnt_sock = accept(serv_sock, (struct sockaddr *)&clnt_adr, &clnt_adr_sz);
29 |
30 | readfp = fdopen(clnt_sock, "r");
31 | writefp = fdopen(dup(clnt_sock), "w"); //复制文件描述符
32 |
33 | fputs("FROM SERVER: Hi~ client? \n", writefp);
34 | fputs("I love all of the world \n", writefp);
35 | fputs("You are awesome! \n", writefp);
36 | fflush(writefp);
37 |
38 | shutdown(fileno(writefp), SHUT_WR); //对 fileno 产生的文件描述符使用 shutdown 进入半关闭状态
39 | fclose(writefp);
40 |
41 | fgets(buf, sizeof(buf), readfp);
42 | fputs(buf, stdout);
43 | fclose(readfp);
44 | return 0;
45 | }
46 |
--------------------------------------------------------------------------------
/ch14/news_sender.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | #define TTL 64
9 | #define BUF_SIZE 30
10 | void error_handling(char *message);
11 |
12 | int main(int argc, char *argv[])
13 | {
14 | int send_sock;
15 | struct sockaddr_in mul_adr;
16 | int time_live = TTL;
17 | FILE *fp;
18 | char buf[BUF_SIZE];
19 | if (argc != 3)
20 | {
21 | printf("Usage : %s \n", argv[0]);
22 | exit(1);
23 | }
24 | send_sock = socket(PF_INET, SOCK_DGRAM, 0); //创建 UDP 套接字
25 | memset(&mul_adr, 0, sizeof(mul_adr));
26 | mul_adr.sin_family = AF_INET;
27 | mul_adr.sin_addr.s_addr = inet_addr(argv[1]); //必须将IP地址设置为多播地址
28 | mul_adr.sin_port = htons(atoi(argv[2]));
29 | //指定套接字中 TTL 的信息
30 | setsockopt(send_sock, IPPROTO_IP, IP_MULTICAST_TTL, (void *)&time_live, sizeof(time_live));
31 | if ((fp = fopen("news.txt", "r")) == NULL)
32 | error_handling("fopen() error");
33 |
34 | while (!feof(fp)) //如果文件没结束就返回0
35 | {
36 | fgets(buf, BUF_SIZE, fp);
37 | sendto(send_sock, buf, strlen(buf), 0, (struct sockaddr *)&mul_adr, sizeof(mul_adr));
38 | sleep(2);
39 | }
40 | fclose(fp);
41 | close(send_sock);
42 | return 0;
43 | }
44 |
45 | void error_handling(char *message)
46 | {
47 | fputs(message, stderr);
48 | fputc('\n', stderr);
49 | exit(1);
50 | }
--------------------------------------------------------------------------------
/ch05/homework/tcp_client_kehou5.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | void error_handling(char *message);
10 |
11 | int main(int argc, char* argv[])
12 | {
13 | int sock;
14 | struct sockaddr_in serv_addr;
15 |
16 | char msg1[]="Hello server!";
17 | char msg2[]="I'm client.";
18 | char msg3[]="Nice to meet you too!";
19 | char* str_arr[]={msg1, msg2, msg3};
20 | char read_buf[100];
21 |
22 | int str_len, i;
23 |
24 | if(argc!=3){
25 | printf("Usage : %s \n", argv[0]);
26 | exit(1);
27 | }
28 |
29 | sock=socket(PF_INET, SOCK_STREAM, 0);
30 | if(sock == -1)
31 | error_handling("socket() error");
32 |
33 | memset(&serv_addr, 0, sizeof(serv_addr));
34 | serv_addr.sin_family=AF_INET;
35 | serv_addr.sin_addr.s_addr=inet_addr(argv[1]);
36 | serv_addr.sin_port=htons(atoi(argv[2]));
37 |
38 | if(connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr))==-1)
39 | error_handling("connect() error!");
40 |
41 | for(i=0; i<3; i++)
42 | {
43 | read(sock, (char*)(&str_len), 4);
44 | read(sock, read_buf, str_len);
45 | puts(read_buf);
46 |
47 | str_len=strlen(str_arr[i])+1;
48 | write(sock, (char*)(&str_len), 4);
49 | write(sock, str_arr[i], str_len);
50 | }
51 | close(sock);
52 | return 0;
53 | }
54 |
55 | void error_handling(char *message)
56 | {
57 | fputs(message, stderr);
58 | fputc('\n', stderr);
59 | exit(1);
60 | }
--------------------------------------------------------------------------------
/ch06/homework/uchar_client.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | #define BUF_SIZE 30
9 | void error_handling(char* message);
10 |
11 | int main(int argc, char* argv[])
12 | {
13 | int sock;
14 | char message[BUF_SIZE];
15 | int str_len;
16 | socklen_t adr_sz;
17 |
18 | struct sockaddr_in serv_adr, from_adr;
19 | if(argc != 3) {
20 | printf("Usage : %s \n", argv[0]);
21 | exit(1);
22 | }
23 |
24 | sock = socket(PF_INET, SOCK_DGRAM, 0);
25 | if(sock == -1)
26 | error_handling("socket() error");
27 |
28 | memset(&serv_adr, 0, sizeof(serv_adr));
29 | serv_adr.sin_family = AF_INET;
30 | serv_adr.sin_addr.s_addr = inet_addr(argv[1]);
31 | serv_adr.sin_port = htons(atoi(argv[2]));
32 |
33 | while(1)
34 | {
35 | fputs("Inset message(q to Quit): ", stdout);
36 | fgets(message, sizeof(message), stdin);
37 | if(!strcmp(message, "q\n") || !strcmp(message, "Q\n"))
38 | break;
39 |
40 | sendto(sock, message, BUF_SIZE, 0, (struct sockaddr*)&serv_adr, sizeof(serv_adr));
41 | adr_sz = sizeof(from_adr);
42 | str_len = recvfrom(sock, message, BUF_SIZE, 0, (struct sockaddr*)&from_adr, &adr_sz);
43 |
44 | message[str_len] = 0;
45 | printf("Message from server: %s", message);
46 | }
47 | close(sock);
48 | return 0;
49 | }
50 |
51 | void error_handling(char* message)
52 | {
53 | fputs(message, stderr);
54 | fputc('\n', stderr);
55 | exit(1);
56 | }
--------------------------------------------------------------------------------
/ch04/echo_client.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | #define BUF_SIZE 1024
9 | void error_handling(char *message);
10 |
11 | int main(int argc, char *argv[])
12 | {
13 | int sock;
14 | char message[BUF_SIZE];
15 | int str_len;
16 | struct sockaddr_in serv_adr;
17 |
18 | if (argc != 3)
19 | {
20 | printf("Usage : %s \n", argv[0]);
21 | exit(1);
22 | }
23 |
24 | sock = socket(PF_INET, SOCK_STREAM, 0);
25 | if (sock == -1)
26 | error_handling("socket() error");
27 |
28 | memset(&serv_adr, 0, sizeof(serv_adr));
29 | serv_adr.sin_family = AF_INET;
30 | serv_adr.sin_addr.s_addr = inet_addr(argv[1]);
31 | serv_adr.sin_port = htons(atoi(argv[2]));
32 |
33 | if (connect(sock, (struct sockaddr *)&serv_adr, sizeof(serv_adr)) == -1)
34 | error_handling("connect() error!");
35 | else
36 | puts("Connected...........");
37 |
38 | while (1)
39 | {
40 | fputs("Input message(Q to quit): ", stdout);
41 | fgets(message, BUF_SIZE, stdin);
42 |
43 | if (!strcmp(message, "q\n") || !strcmp(message, "Q\n"))
44 | break;
45 |
46 | write(sock, message, strlen(message));
47 | str_len = read(sock, message, BUF_SIZE - 1);
48 | message[str_len] = 0;
49 | printf("Message from server: %s", message);
50 | }
51 | close(sock);
52 | return 0;
53 | }
54 |
55 | void error_handling(char *message)
56 | {
57 | fputs(message, stderr);
58 | fputc('\n', stderr);
59 | exit(1);
60 | }
--------------------------------------------------------------------------------
/ch05/homework/tcp_server_kehou6.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include