From 4e8142a9875d3cc0cc5081115927879055e97574 Mon Sep 17 00:00:00 2001 From: caixiongjiang <1837278011@qq.com> Date: Thu, 14 Apr 2022 16:28:46 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A1=A5=E5=85=85=E8=AF=BE=E5=90=8E=E4=BD=9C?= =?UTF-8?q?=E4=B8=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ch05/homework/tcp_client_kehou5.c | 60 +++++++++++++ ch05/homework/tcp_client_kehou6.c | 59 ++++++++++++ ch05/homework/tcp_server_kehou5.c | 78 ++++++++++++++++ ch05/homework/tcp_server_kehou6.c | 71 +++++++++++++++ ch06/homework/uchar_client.c | 56 ++++++++++++ ch06/homework/uchar_server.c | 58 ++++++++++++ ch10/homework/kehou3.c | 26 ++++++ ch10/homework/kehou5.c | 33 +++++++ ch11/homework/kehou4.c | 42 +++++++++ ch17/homework/char_EPETserv.c | 143 ++++++++++++++++++++++++++++++ ch17/homework/char_EPLTserv.c | 124 ++++++++++++++++++++++++++ ch17/homework/chat_clnt.c | 93 +++++++++++++++++++ ch18/homework/echo_client.c | 58 ++++++++++++ ch18/homework/echo_threadserv.c | 78 ++++++++++++++++ 14 files changed, 979 insertions(+) create mode 100644 ch05/homework/tcp_client_kehou5.c create mode 100644 ch05/homework/tcp_client_kehou6.c create mode 100644 ch05/homework/tcp_server_kehou5.c create mode 100644 ch05/homework/tcp_server_kehou6.c create mode 100644 ch06/homework/uchar_client.c create mode 100644 ch06/homework/uchar_server.c create mode 100644 ch10/homework/kehou3.c create mode 100644 ch10/homework/kehou5.c create mode 100644 ch11/homework/kehou4.c create mode 100644 ch17/homework/char_EPETserv.c create mode 100644 ch17/homework/char_EPLTserv.c create mode 100644 ch17/homework/chat_clnt.c create mode 100644 ch18/homework/echo_client.c create mode 100644 ch18/homework/echo_threadserv.c diff --git a/ch05/homework/tcp_client_kehou5.c b/ch05/homework/tcp_client_kehou5.c new file mode 100644 index 0000000..8321853 --- /dev/null +++ b/ch05/homework/tcp_client_kehou5.c @@ -0,0 +1,60 @@ +#include +#include +#include +#include +#include +#include +#include + +void error_handling(char *message); + +int main(int argc, char* argv[]) +{ + int sock; + struct sockaddr_in serv_addr; + + char msg1[]="Hello server!"; + char msg2[]="I'm client."; + char msg3[]="Nice to meet you too!"; + char* str_arr[]={msg1, msg2, msg3}; + char read_buf[100]; + + int str_len, i; + + if(argc!=3){ + printf("Usage : %s \n", argv[0]); + exit(1); + } + + sock=socket(PF_INET, SOCK_STREAM, 0); + if(sock == -1) + error_handling("socket() error"); + + memset(&serv_addr, 0, sizeof(serv_addr)); + serv_addr.sin_family=AF_INET; + serv_addr.sin_addr.s_addr=inet_addr(argv[1]); + serv_addr.sin_port=htons(atoi(argv[2])); + + if(connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr))==-1) + error_handling("connect() error!"); + + for(i=0; i<3; i++) + { + read(sock, (char*)(&str_len), 4); + read(sock, read_buf, str_len); + puts(read_buf); + + str_len=strlen(str_arr[i])+1; + write(sock, (char*)(&str_len), 4); + write(sock, str_arr[i], str_len); + } + close(sock); + return 0; +} + +void error_handling(char *message) +{ + fputs(message, stderr); + fputc('\n', stderr); + exit(1); +} \ No newline at end of file diff --git a/ch05/homework/tcp_client_kehou6.c b/ch05/homework/tcp_client_kehou6.c new file mode 100644 index 0000000..6d59eb7 --- /dev/null +++ b/ch05/homework/tcp_client_kehou6.c @@ -0,0 +1,59 @@ +/***************************************recvsend_clnt.c***************************/ +#include +#include +#include +#include +#include +#include + +#define BUF_SIZE 30 +void error_handling(char *message); + +int main(int argc, char *argv[]) +{ + int sd; + FILE *fp; + + char buf[BUF_SIZE]; + char file_name[BUF_SIZE]; + int read_cnt; + struct sockaddr_in serv_adr; + if(argc!=3) { + printf("Usage: %s \n", argv[0]); + exit(1); + } + + //输入文件名 + printf("Input file name: "); + scanf("%s", file_name); + //打开文件名 + fp=fopen(file_name, "wb"); + + //创建套接字 + sd=socket(PF_INET, SOCK_STREAM, 0); + //初始化 + memset(&serv_adr, 0, sizeof(serv_adr)); + serv_adr.sin_family=AF_INET; + serv_adr.sin_addr.s_addr=inet_addr(argv[1]); + serv_adr.sin_port=htons(atoi(argv[2])); + + connect(sd, (struct sockaddr*)&serv_adr, sizeof(serv_adr)); + //写入要传输的文件 + write(sd, file_name, strlen(file_name)+1); + + while((read_cnt=read(sd, buf, BUF_SIZE))!=0) + fwrite((void*)buf, 1, read_cnt, fp); + + fclose(fp); + close(sd); + return 0; +} + +void error_handling(char *message) +{ + fputs(message, stderr); + fputc('\n', stderr); + exit(1); +} + + diff --git a/ch05/homework/tcp_server_kehou5.c b/ch05/homework/tcp_server_kehou5.c new file mode 100644 index 0000000..6f1e0ff --- /dev/null +++ b/ch05/homework/tcp_server_kehou5.c @@ -0,0 +1,78 @@ +#include +#include +#include +#include +#include +#include +#include + +void error_handling(char *message); + +int main(int argc, char *argv[]) +{ + int serv_sock; + int clnt_sock; + int str_len, i; + + struct sockaddr_in serv_addr; + struct sockaddr_in clnt_addr; + socklen_t clnt_addr_size; + + char msg1[]="Hello client!"; + char msg2[]="I'm server."; + char msg3[]="Nice to meet you."; + char* str_arr[]={msg1, msg2, msg3}; + char read_buf[100]; + + if(argc!=2){ + printf("Usage : %s \n", argv[0]); + exit(1); + } + + serv_sock=socket(PF_INET, SOCK_STREAM, 0); + if(serv_sock == -1) + error_handling("socket() error"); + + memset(&serv_addr, 0, sizeof(serv_addr)); + serv_addr.sin_family=AF_INET; + serv_addr.sin_addr.s_addr=htonl(INADDR_ANY); + serv_addr.sin_port=htons(atoi(argv[1])); + + if(bind(serv_sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr))==-1) + error_handling("bind() error"); + + if(listen(serv_sock, 5)==-1) + error_handling("listen() error"); + + clnt_addr_size=sizeof(clnt_addr); + clnt_sock=accept(serv_sock, (struct sockaddr*)&clnt_addr,&clnt_addr_size); + if(clnt_sock==-1) + error_handling("accept() error"); + + for(i=0; i<3; i++) + { + //需要写入的字符串的长度 + str_len=strlen(str_arr[i])+1; + write(clnt_sock, (char*)(&str_len), 4); + //写入字符串 + write(clnt_sock, str_arr[i], str_len); + + //读取的字符串长度 + read(clnt_sock, (char*)(&str_len), 4); + //读取的字符串 + read(clnt_sock, read_buf, str_len); + puts(read_buf); + } + + close(clnt_sock); + close(serv_sock); + return 0; +} + +void error_handling(char *message) +{ + fputs(message, stderr); + fputc('\n', stderr); + exit(1); +} + diff --git a/ch05/homework/tcp_server_kehou6.c b/ch05/homework/tcp_server_kehou6.c new file mode 100644 index 0000000..951d977 --- /dev/null +++ b/ch05/homework/tcp_server_kehou6.c @@ -0,0 +1,71 @@ +#include +#include +#include +#include +#include +#include + +#define BUF_SIZE 30 +void error_handling(char *message); + +int main(int argc, char *argv[]) +{ + int serv_sd, clnt_sd; + FILE * fp; + char buf[BUF_SIZE]; + char file_name[BUF_SIZE]; + int read_cnt; + + struct sockaddr_in serv_adr, clnt_adr; + socklen_t clnt_adr_sz; + + if(argc!=2) { + printf("Usage: %s \n", argv[0]); + exit(1); + } + + serv_sd=socket(PF_INET, SOCK_STREAM, 0); + + memset(&serv_adr, 0, sizeof(serv_adr)); + serv_adr.sin_family=AF_INET; + serv_adr.sin_addr.s_addr=htonl(INADDR_ANY); + serv_adr.sin_port=htons(atoi(argv[1])); + + bind(serv_sd, (struct sockaddr*)&serv_adr, sizeof(serv_adr)); + listen(serv_sd, 5); + + clnt_adr_sz=sizeof(clnt_adr); + clnt_sd=accept(serv_sd, (struct sockaddr*)&clnt_adr, &clnt_adr_sz); + + //读取客户端传入的文件名 + read(clnt_sd, file_name, BUF_SIZE); + //打开文件 + fp=fopen(file_name, "rb"); + //文件存在 + if(fp!=NULL) + { + while(1) + { + read_cnt=fread((void*)buf, 1, BUF_SIZE, fp); + if(read_cnt +#include +#include +#include +#include +#include + +#define BUF_SIZE 30 +void error_handling(char* message); + +int main(int argc, char* argv[]) +{ + int sock; + char message[BUF_SIZE]; + int str_len; + socklen_t adr_sz; + + struct sockaddr_in serv_adr, from_adr; + if(argc != 3) { + printf("Usage : %s \n", argv[0]); + exit(1); + } + + sock = socket(PF_INET, SOCK_DGRAM, 0); + if(sock == -1) + error_handling("socket() error"); + + memset(&serv_adr, 0, sizeof(serv_adr)); + serv_adr.sin_family = AF_INET; + serv_adr.sin_addr.s_addr = inet_addr(argv[1]); + serv_adr.sin_port = htons(atoi(argv[2])); + + while(1) + { + fputs("Inset message(q to Quit): ", stdout); + fgets(message, sizeof(message), stdin); + if(!strcmp(message, "q\n") || !strcmp(message, "Q\n")) + break; + + sendto(sock, message, BUF_SIZE, 0, (struct sockaddr*)&serv_adr, sizeof(serv_adr)); + adr_sz = sizeof(from_adr); + str_len = recvfrom(sock, message, BUF_SIZE, 0, (struct sockaddr*)&from_adr, &adr_sz); + + message[str_len] = 0; + printf("Message from server: %s", message); + } + close(sock); + return 0; +} + +void error_handling(char* message) +{ + fputs(message, stderr); + fputc('\n', stderr); + exit(1); +} \ No newline at end of file diff --git a/ch06/homework/uchar_server.c b/ch06/homework/uchar_server.c new file mode 100644 index 0000000..ea45df0 --- /dev/null +++ b/ch06/homework/uchar_server.c @@ -0,0 +1,58 @@ +#include +#include +#include +#include +#include +#include + +#define BUF_SIZE 30 +void error_handling(char* message); + +int main(int argc, char* argv[]) +{ + int serv_sock; + char message[BUF_SIZE]; + int str_len; + socklen_t clnt_adr_sz; + + struct sockaddr_in serv_adr, clnt_adr; + if(argc != 2) { + printf("Usage : %s \n", argv[0]); + exit(1); + } + + serv_sock = socket(PF_INET, SOCK_DGRAM, 0); + if(serv_sock == -1) + error_handling("socket() error"); + + memset(&serv_adr, 0, sizeof(serv_adr)); + serv_adr.sin_family = AF_INET; + serv_adr.sin_addr.s_addr = htonl(INADDR_ANY); + serv_adr.sin_port = htons(atoi(argv[1])); + + if(bind(serv_sock, (struct sockaddr*)&serv_adr, sizeof(serv_adr)) == -1) + error_handling("bind() error"); + + clnt_adr_sz = sizeof(clnt_adr); + while(1) + { + str_len = recvfrom(serv_sock, message, BUF_SIZE, 0, (struct sockaddr*)&clnt_adr, &clnt_adr_sz); + message[str_len] = 0; + printf("Message from client: %s\n", message); + + fputs("Insert message(q to Quit): ", stdout); + fgets(message, sizeof(message), stdin); + if(!strcmp(message, "q\n") || !strcmp(message, "Q\n")) + break; + sendto(serv_sock, message, strlen(message), 0, (struct sockaddr*)&clnt_adr, clnt_adr_sz); + } + close(serv_sock); + return 0; +} + +void error_handling(char* message) +{ + fputs(message, stderr); + fputc('\n', stderr); + exit(1); +} \ No newline at end of file diff --git a/ch10/homework/kehou3.c b/ch10/homework/kehou3.c new file mode 100644 index 0000000..554ff30 --- /dev/null +++ b/ch10/homework/kehou3.c @@ -0,0 +1,26 @@ +#include +#include +#include + +int main(int argc, char *argv[]) +{ + pid_t pid; + int sockfd = socket(PF_INET, SOCK_STREAM, 0); + + pid = fork(); + if(pid == 0) + { + printf("Child sockfd: %d \n", sockfd); + } + else + { + printf("Parent sockfd: %d \n", sockfd); + } + return 0; +} + +/* +结果: +Parent sockfd: 3 +Child sockfd: 3 +*/ \ No newline at end of file diff --git a/ch10/homework/kehou5.c b/ch10/homework/kehou5.c new file mode 100644 index 0000000..afc2e91 --- /dev/null +++ b/ch10/homework/kehou5.c @@ -0,0 +1,33 @@ +#include +#include +#include + +void ctrl_handling(int sig); + +int main(int argc, char *argv[]) +{ + struct sigaction act; + act.sa_handler = ctrl_handling; + sigemptyset(&act.sa_mask); + act.sa_flags = 0; + sigaction(SIGINT, &act, 0);//输入ctrl+c发出信号 + + while(1) + { + sleep(1); + puts("美好的一天!"); + } + return 0; +} + +void ctrl_handling(int sig) +{ + char c; + if(sig == SIGINT) + { + fputs("Do you want to exit(Y to exit)?", stdout); + scanf("%c", &c); + if(c == 'y' || c == 'Y') + exit(1); + } +} \ No newline at end of file diff --git a/ch11/homework/kehou4.c b/ch11/homework/kehou4.c new file mode 100644 index 0000000..170caa0 --- /dev/null +++ b/ch11/homework/kehou4.c @@ -0,0 +1,42 @@ +#include +#include +#include +#define BUF_SIZE 30 + +int main(int argc, char *argv[]) +{ + int fds1[2], fds2[2]; + //const char* 以"\0"作为结束符 + char str1[] = "Do you like cooffee?"; + char str2[] = "I like coffee"; + char str3[] = "I like long legs"; + char * str_arr[] = {str1, str2, str3}; + char buf[BUF_SIZE]; + pid_t pid; + int i; + + pipe(fds1), pipe(fds2); + pid = fork(); + + if(pid == 0) + { + for(i = 0; i < 3; ++i) + { + //strlen所作的是一个计数器的工作,它从内存的某个位置(可以是字符串开头,中间某个位置,甚至是某个不确定的内存区域)开始扫描, + //直到碰到第一个字符串结束符'\0'为止,然后返回计数器值(长度不包含'\0') + write(fds1[1], str_arr[i], strlen(str_arr[i]) + 1);//这里长度必须加上1,将字符串结束符加进去,否则会发生消息错乱 + read(fds2[0], buf, BUF_SIZE); + printf("子进程收到的消息:%s\n", buf); + } + } + else + { + for(i = 0; i < 3; ++i) + { + read(fds1[0], buf, BUF_SIZE); + printf("父进程收到的消息:%s\n", buf); + write(fds2[1], str_arr[i], strlen(str_arr[i]) + 1); + } + } + return 0; +} \ No newline at end of file diff --git a/ch17/homework/char_EPETserv.c b/ch17/homework/char_EPETserv.c new file mode 100644 index 0000000..9c09449 --- /dev/null +++ b/ch17/homework/char_EPETserv.c @@ -0,0 +1,143 @@ +//边缘触发 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BUF_SIZE 100 +#define MAX_CLNT 256 +#define EPOLL_SIZE 50 + +void setnonblockingmode(int fd); +void error_handling(char *buf); +void send_msg(char * msg, int len); + +int clnt_cnt = 0; +int clnt_socks[MAX_CLNT]; + +int main(int argc, char *argv[]) +{ + int serv_sock, clnt_sock; + struct sockaddr_in serv_adr, clnt_adr; + socklen_t adr_sz; + int str_len, i; + char buf[BUF_SIZE]; + + struct epoll_event *ep_events; + struct epoll_event event; + int epfd, event_cnt; + + if(argc!=2) { + printf("Usage : %s \n", argv[0]); + exit(1); + } + + serv_sock = socket(PF_INET, SOCK_STREAM, 0); + memset(&serv_adr, 0, sizeof(serv_adr)); + serv_adr.sin_family = AF_INET; + serv_adr.sin_addr.s_addr = htonl(INADDR_ANY); + serv_adr.sin_port = htons(atoi(argv[1])); + + if(bind(serv_sock, (struct sockaddr*) &serv_adr, sizeof(serv_adr)) == -1) + error_handling("bind() error"); + if(listen(serv_sock, 5) == -1) + error_handling("listen() error"); + + epfd = epoll_create(EPOLL_SIZE); + ep_events = malloc(sizeof(struct epoll_event)*EPOLL_SIZE); + + setnonblockingmode(serv_sock); + event.events = EPOLLIN; + event.data.fd = serv_sock; + epoll_ctl(epfd, EPOLL_CTL_ADD, serv_sock, &event); + + while(1) + { + event_cnt = epoll_wait(epfd, ep_events, EPOLL_SIZE, -1); + if(event_cnt == -1) + { + puts("epoll_wait() error"); + break; + } + + puts("return epoll_wait"); + for(i = 0; i < event_cnt; ++i) + { + if(ep_events[i].data.fd == serv_sock) + { + adr_sz = sizeof(clnt_adr); + clnt_sock = accept(serv_sock, (struct sockaddr*)&clnt_adr, &adr_sz); + setnonblockingmode(clnt_sock); + event.events = EPOLLIN|EPOLLET; + event.data.fd = clnt_sock; + epoll_ctl(epfd, EPOLL_CTL_ADD, clnt_sock, &event); + clnt_socks[clnt_cnt++] = clnt_sock; + printf("connected client: %d \n", clnt_sock); + } + else + { + while(1) + { + str_len = read(ep_events[i].data.fd, buf, BUF_SIZE); + if(str_len == 0) // close request! + { + epoll_ctl(epfd, EPOLL_CTL_DEL, ep_events[i].data.fd, NULL); + close(ep_events[i].data.fd); + + for(i = 0; i < clnt_cnt; ++i) + { + if(ep_events[i].data.fd == clnt_socks[i]) + { + while(i++ < clnt_cnt-1) + clnt_socks[i] = clnt_socks[i+1]; + break; + } + } + --clnt_cnt; + printf("closed client: %d \n", ep_events[i].data.fd); + break; + } + else if(str_len < 0) + { + if(errno == EAGAIN) + break; + } + else + { + send_msg(buf, str_len); + } + } + } + } + } + close(serv_sock); + close(epfd); + return 0; +} + + +void send_msg(char * msg, int len) // send to all +{ + int i; + for(i = 0; i < clnt_cnt; ++i) + write(clnt_socks[i], msg, len); +} + +//设置为非阻塞模式 +void setnonblockingmode(int fd) +{ + int flag = fcntl(fd, F_GETFL, 0); + fcntl(fd, F_SETFL, flag|O_NONBLOCK); +} + +void error_handling(char *buf) +{ + fputs(buf, stderr); + fputc('\n', stderr); + exit(1); +} diff --git a/ch17/homework/char_EPLTserv.c b/ch17/homework/char_EPLTserv.c new file mode 100644 index 0000000..0059346 --- /dev/null +++ b/ch17/homework/char_EPLTserv.c @@ -0,0 +1,124 @@ +//条件触发 +#include +#include +#include +#include +#include +#include +#include +#include + +#define BUF_SIZE 100 +#define MAX_CLNT 256 +#define EPOLL_SIZE 50 +void error_handling(char *buf); +void send_msg(char *msg, int len); + +int clnt_cnt = 0; +int clnt_socks[MAX_CLNT]; + +int main(int argc, char *argv[]) +{ + int serv_sock, clnt_sock; + struct sockaddr_in serv_adr, clnt_adr; + socklen_t adr_sz; + int str_len, i; + char buf[BUF_SIZE]; + + struct epoll_event *ep_events; + struct epoll_event event; + int epfd, event_cnt; + + if(argc != 2) { + printf("Usage: %s \n", argv[0]); + exit(1); + } + + serv_sock = socket(PF_INET, SOCK_STREAM, 0); + memset(&serv_adr, 0, sizeof(serv_adr)); + serv_adr.sin_family = AF_INET; + serv_adr.sin_addr.s_addr = htonl(INADDR_ANY); + serv_adr.sin_port = htons(atoi(argv[1])); + + if(bind(serv_sock, (struct sockaddr*) &serv_adr, sizeof(serv_adr)) == -1) + error_handling("bind() error"); + if(listen(serv_sock, 5) == -1) + error_handling("listen() error"); + + //创建epoll例程 + epfd = epoll_create(EPOLL_SIZE); + //动态分配内存 + ep_events = malloc(sizeof(struct epoll_event)*EPOLL_SIZE); + + event.events = EPOLLIN;//事件类型为需要读取的情况 + event.data.fd = serv_sock; + //在epoll例程中注册服务端套接字 + epoll_ctl(epfd, EPOLL_CTL_ADD, serv_sock, &event); + + while(1) + { + //获取发生改变的文件描述符数量 + event_cnt = epoll_wait(epfd, ep_events, EPOLL_SIZE, -1); + if(event_cnt == -1) + break; + + for(i = 0; i < event_cnt; ++i) + { + if(ep_events[i].data.fd == serv_sock)//serv_sock + { + adr_sz = sizeof(clnt_adr); + clnt_sock = accept(serv_sock, (struct sockaddr*) &clnt_adr, &adr_sz); + event.events = EPOLLIN; + event.data.fd = clnt_sock; + //在epoll例程中注册clnt_sock套接字 + epoll_ctl(epfd, EPOLL_CTL_ADD, clnt_sock, &event); + clnt_socks[clnt_cnt++] = clnt_sock; + printf("connected client: %d \n", clnt_sock); + } + else //clnt_sock + { + str_len = read(ep_events[i].data.fd, buf, BUF_SIZE); + if(str_len == 0) + { + //在例程中删除clnt_sock套接字 + epoll_ctl(epfd, EPOLL_CTL_DEL, ep_events[i].data.fd, NULL); + //关闭clnt_sock套接字 + close(ep_events[i].data.fd); + printf("closed client: %d \n", ep_events[i].data.fd); + + for(i = 0; i < clnt_cnt; ++i) + { + if(clnt_sock == clnt_socks[i]) + { + while(i++ < clnt_cnt - 1) + clnt_socks[i] = clnt_socks[i + 1]; + break; + } + } + --clnt_cnt; + } + else + { + send_msg(buf, str_len); + } + } + } + } + close(serv_sock); + close(epfd); + return 0; +} + +void send_msg(char * msg, int len) +{ + int i; + for(i = 0; i < clnt_cnt; ++i) + write(clnt_socks[i], msg, len); +} + +void error_handling(char *buf) +{ + fputs(buf, stderr); + fputc('\n', stderr); + exit(1); +} \ No newline at end of file diff --git a/ch17/homework/chat_clnt.c b/ch17/homework/chat_clnt.c new file mode 100644 index 0000000..b585191 --- /dev/null +++ b/ch17/homework/chat_clnt.c @@ -0,0 +1,93 @@ +#include +#include +#include +#include +#include +#include +#include + +#define BUF_SIZE 100 +#define NAME_SIZE 20 + +void * send_msg(void * arg); +void * recv_msg(void * arg); +void error_handling(char * msg); + +char name[NAME_SIZE] = "[DEFAULT]"; +char msg[BUF_SIZE]; + +int main(int argc, char *argv[]) +{ + int sock; + struct sockaddr_in adr; + pthread_t send_thread, recv_thread; + void * thread_return;//线程返回值 + if(argc != 4) { + printf("Usage: %s \n", argv[0]); + exit(1); + } + + sprintf(name, "[%s]", argv[3]);//把名字写入name数组 + sock = socket(PF_INET, SOCK_STREAM, 0); + + memset(&adr, 0, sizeof(adr)); + adr.sin_family = AF_INET; + adr.sin_addr.s_addr = inet_addr(argv[1]); + adr.sin_port = htons(atoi(argv[2])); + + if(connect(sock, (struct sockaddr*) &adr, sizeof(adr)) == -1) + error_handling("connect() error"); + /*线程创建*/ + pthread_create(&send_thread, NULL, send_msg, (void *)&sock); + pthread_create(&recv_thread, NULL, recv_msg, (void *)&sock); + /*进程阻塞,进入发送消息的线程*/ + pthread_join(send_thread, &thread_return); + /*进程阻塞,进入接收消息的线程*/ + pthread_join(recv_thread, &thread_return); + close(sock); + return 0; +} + +void * send_msg(void * arg) +{ + int sock = *((int *)arg); + char name_msg[NAME_SIZE + BUF_SIZE]; + + while(1) + { + fputs("Input message(q to quit):\n", stdout); + fgets(msg, BUF_SIZE, stdin); + if(!(strcmp(msg, "q\n")) || !strcmp(msg, "Q\n")) + { + close(sock); + exit(0); + } + sprintf(name_msg, "%s %s", name, msg); + write(sock, name_msg, strlen(name_msg));//strlen()函数碰到'\0'会结束 + } + return NULL; +} + +void * recv_msg(void * arg) +{ + int sock = *((int *)arg); + char name_msg[NAME_SIZE + BUF_SIZE]; + int str_len; + + while(1) + { + str_len = read(sock, name_msg, NAME_SIZE + BUF_SIZE - 1); + if(str_len == -1) + return (void *)-1; + name_msg[str_len] = 0; + fputs(name_msg, stdout); + } + return NULL; +} + +void error_handling(char *msg) +{ + fputs(msg, stderr); + fputc('\n', stderr); + exit(1); +} \ No newline at end of file diff --git a/ch18/homework/echo_client.c b/ch18/homework/echo_client.c new file mode 100644 index 0000000..e1e78a8 --- /dev/null +++ b/ch18/homework/echo_client.c @@ -0,0 +1,58 @@ +#include +#include +#include +#include +#include + +#define BUF_SIZE 1024 +void error_handling(char* message); + +int main(int argc, char* argv[]) +{ + int sock; + char message[BUF_SIZE]; + int str_len; + struct sockaddr_in serv_adr; + + if(argc != 3) { + printf("Usage : %s \n", argv[0]); + exit(1); + } + /*创建tcp套接字*/ + sock = socket(PF_INET, SOCK_STREAM, 0); + if(sock == -1) + error_handling("socket() error"); + /*初始化*/ + memset(&serv_adr, 0, sizeof(serv_adr)); + serv_adr.sin_family = AF_INET; + serv_adr.sin_addr.s_addr = inet_addr(argv[1]);//string转大端序整型 + serv_adr.sin_port = htons(atoi(argv[2])); + /*建立连接*/ + if(connect(sock, (struct sockaddr*)&serv_adr, sizeof(serv_adr)) == -1) + error_handling("connect() error"); + else + puts("Connected..........."); + + while(1) + { + fputs("Input message(Q to quit): ", stdout); + fgets(message, BUF_SIZE, stdin); + //实现按q或者Q退出 + if(!strcmp(message, "q\n") || !strcmp(message, "Q\n")) + break; + + write(sock, message, strlen(message)); + str_len = read(sock, message, BUF_SIZE - 1); + message[str_len] = 0; + printf("Message from server: %s", message); + } + close(sock); + return 0; +} + +void error_handling(char* message) +{ + fputs(message, stderr); + fputc('\n',stderr); + exit(1); +} \ No newline at end of file diff --git a/ch18/homework/echo_threadserv.c b/ch18/homework/echo_threadserv.c new file mode 100644 index 0000000..f9f6540 --- /dev/null +++ b/ch18/homework/echo_threadserv.c @@ -0,0 +1,78 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#define BUF_SIZE 100 +void * handle_clnt(void * arg); +void error_handling(char *buf); + +char buf[BUF_SIZE]; +pthread_mutex_t mutx; + +int main(int argc, char *argv[]) +{ + int serv_sock, clnt_sock; + struct sockaddr_in serv_adr, clnt_adr; + int clnt_adr_sz; + pthread_t t_id; + + if(argc != 2) { + printf("Usage : %s \n", argv[0]); + exit(1); + } + + pthread_mutex_init(&mutx, NULL); + serv_sock = socket(PF_INET, SOCK_STREAM, 0); + memset(&serv_adr, 0, sizeof(serv_adr)); + serv_adr.sin_family = AF_INET; + serv_adr.sin_addr.s_addr = htonl(INADDR_ANY); + serv_adr.sin_port = htons(atoi(argv[1])); + + if(bind(serv_sock, (struct sockaddr*) &serv_adr, sizeof(serv_adr)) == -1) + error_handling("bind() error"); + if(listen(serv_sock, 5) == -1) + error_handling("listen() error"); + + while(1) + { + clnt_adr_sz = sizeof(clnt_adr); + clnt_sock = accept(serv_sock, (struct sockaddr*)&clnt_adr,&clnt_adr_sz); + pthread_create(&t_id, NULL, handle_clnt, (void*)&clnt_sock); + pthread_detach(t_id); + printf("Connected client IP: %s \n", inet_ntoa(clnt_adr.sin_addr)); + } + + close(serv_sock); + return 0; +} + +void * handle_clnt(void * arg) +{ + int clnt_sock = *((int*)arg); + int str_len = 0; + + while(1) + { + pthread_mutex_lock(&mutx); + str_len = read(clnt_sock, buf, sizeof(buf)); + if(str_len <= 0) + break; + else + write(clnt_sock, buf, str_len); + pthread_mutex_unlock(&mutx); + } + + close(clnt_sock); + return NULL; +} +void error_handling(char *buf) +{ + fputs(buf, stderr); + fputc('\n', stderr); + exit(1); +}