diff --git a/day3/homework/02.jpg b/day3/homework/02.jpg new file mode 100644 index 0000000..f6fbca5 Binary files /dev/null and b/day3/homework/02.jpg differ diff --git a/day3/homework/h3 b/day3/homework/h3 new file mode 100755 index 0000000..e618005 Binary files /dev/null and b/day3/homework/h3 differ diff --git a/day3/homework/h3.c b/day3/homework/h3.c new file mode 100644 index 0000000..d5e7edd --- /dev/null +++ b/day3/homework/h3.c @@ -0,0 +1,95 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* +./a.out server_ip 下载的文件名 +*/ +int main(int argc, char const *argv[]) +{ + if (argc != 3) + { + printf("usage: %s server_ip filename\n", argv[0]); + return -1; + } + + int sock_fd = socket(AF_INET, SOCK_DGRAM, 0); + if (sock_fd < 0) + { + perror("socket"); + return -1; + } + + struct stat st; + stat(argv[2], &st); + int tsize = st.st_size; + // 生成请求数据包 + char request[64]; + // char *tsize = 0; + int request_size = sprintf(request, "%c%c%s%c%s%c%d%c", 0, 1, argv[2], 0, "octet", 0, tsize, 0); + + // 发送请求 + struct sockaddr_in server_addr; + bzero(&server_addr, sizeof(server_addr)); + server_addr.sin_family = AF_INET; + server_addr.sin_port = htons(69); // 服务器TFTP端口 + server_addr.sin_addr.s_addr = inet_addr(argv[1]); // 服务器地址 + + sendto(sock_fd, request, request_size, 0, (struct sockaddr *)&server_addr, sizeof(server_addr)); + + char buf[516] = ""; + struct sockaddr_in data_addr; + socklen_t data_addr_len = sizeof(data_addr); + bzero(&data_addr, sizeof(data_addr)); + ssize_t len = recvfrom(sock_fd, buf, 516, 0, (struct sockaddr *)&data_addr, &data_addr_len); + + // 验证接收的数据是否是 OK + if (buf[1] == 3) + { + // printf("收到的文件大小为 %d\n", tsize); + // 创建本地文件的描述符(打开或创建文件) + int fd = open(argv[2], O_CREAT | O_WRONLY, 0666); + + while (1) + { + printf("文件名为 %s,文件大小为 %s\n", argv[2], buf + 2); + + // 收到的是数据报 + write(fd, buf + 4, len - 4); + // 回ACK + buf[1] = 4; + // buf[2] = "tsize"; + sendto(sock_fd, buf, 4, 0, (struct sockaddr *)&data_addr, sizeof(data_addr)); + if (len < 516) + { + printf("数据接收完成\n"); + break; + } + + bzero(&data_addr, data_addr_len); + bzero(buf, sizeof(buf)); + len = recvfrom(sock_fd, buf, 516, 0, (struct sockaddr *)&data_addr, &data_addr_len); + } + + close(fd); + } + else if (buf[1] == 5) + { + // 收到的是错误信息 + printf("error: %s\n", buf + 4); + } + // else if (buf[1] == 6) + // { + // // 收到OACK包,包含请求选项回传的值 + // printf("文件名为 %s,文件大小为 %s\n", argv[2], buf + 2); + // } + + close(sock_fd); + return 0; +} diff --git a/day4/test.c b/day4/test.c new file mode 100644 index 0000000..238e27b --- /dev/null +++ b/day4/test.c @@ -0,0 +1,196 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#define BUFFLEN 1024 //缓冲区的大小 +#define SERVER_PORT 1235 //端口号 +#define HTTP_FILENAME_LEN 256 + +struct doc_type +{ + char *suffix; + char *type; +}; +//返回内容对应 MIME 类型 +struct doc_type file_type[] = +{ + { "html", "text/html" }, + { "ico", "image/x-icon" }, + { NULL, NULL } +}; +void * threadFun(void * args); +void handle_connect(int serv_sock); +void http_parse_request_cmd(char *buf,char *file_name, char *suffix); +char *http_get_type_by_suffix(const char *suffix); + +char *http_res_hdr_tmpl = "HTTP/1.1 200 OK\nServer: bianchengbang\n" +"Accept-Ranges: bytes\nContent-Length: %d\nConnection: closed\n" +"Content-Type: %s\n\n"; + +int main() { + int serv_sock; + struct sockaddr_in serv_addr; + //创建套接字 + if ((serv_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) { + printf("套接字创建失败\n"); + exit(0); + } + + //将套接字与任意 IP 地址和 1234 端口进行绑定 + 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(SERVER_PORT); + if (bind(serv_sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) == -1) { + close(serv_sock); + printf("bind()执行失败\n"); + exit(0); + } + + //让套接字进入被动监听状态 + if (listen(serv_sock, SOMAXCONN) == -1) { + close(serv_sock); + printf("listen()执行失败\n"); + exit(0); + } + + handle_connect(serv_sock); + close(serv_sock); + return 0; +} + +void handle_connect(int serv_sock){ + int clnt_sock; + struct sockaddr_in clnt_addr; + socklen_t clnt_addr_size = sizeof(clnt_addr); + //死循环,持续不断地接收任意客户端发来的请求 + while(1){ + clnt_sock = accept(serv_sock, (struct sockaddr*)&clnt_addr, &clnt_addr_size);//接收客户端发来的请求 + //单独创建一个线程,处理客户端的请求 + if(clnt_sock >0){ + pthread_t myThread; + int ret; + //threadFun() 为线程要执行的函数,clnt_sock 将作为实参传递给 threadFun() 函数 + ret = pthread_create(&myThread, NULL, threadFun, &clnt_sock); + if (ret != 0) { + printf("线程创建失败\n"); + exit(0); + } + } + } +} + +void * threadFun(void * args) { + //将子线程和主线程脱离,子线程执行结束后自动释放资源 + pthread_detach(pthread_self()); + int clnt_sock = *(int*)args; + char buff[BUFFLEN]={0}; + //获取http请求的字符串,num 为字符串的长度 + int num = read(clnt_sock, buff, sizeof(buff)); + if (num > 0) { + FILE * fp = NULL; + int nCount = 0; + int fp_has = 1,fp_type = 1; + int file_len, hdr_len; + char *type = NULL; + char http_header[BUFFLEN]; + char file_name[HTTP_FILENAME_LEN] = { 0 }, suffix[16] = { 0 }; + //获取目标文件(含路径)和后缀名 + http_parse_request_cmd(buff, file_name, suffix); + //获取文件对应的 MIME 类型 + type = http_get_type_by_suffix(suffix); + //如果类型未找到,则向客户端发送 errno.html 文件 + if (type == NULL) + { + fp_type = 0; + printf("访问的文件类型(后缀名)不匹配\n"); + type = http_get_type_by_suffix("html"); + fp = fopen("errno.html","rb"); + }else{ + fp = fopen(file_name, "rb"); + //如果服务器未找到目标文件,向客户端发送 errno.html 文件 + if (fp == NULL) { + fp_has = 0; + fp = fopen("errno.html","rb"); + } + } + //计算文件中包含的字节数 + fseek(fp, 0, SEEK_END); + file_len = ftell(fp); + fseek(fp, 0, SEEK_SET); + //更新 http 响应的字符串 + hdr_len = sprintf(http_header, http_res_hdr_tmpl, file_len, type); + //向客户端发送响应行、响应头和空行 + write(clnt_sock, http_header, hdr_len); + + if(fp_type == 1){ + if (fp_has == 0) { + printf("服务器不存在 %s 文件\n", file_name); + } + else { + printf("服务器存在 %s 文件,发送中...\n",file_name); + } + } + //向客户端发送文件内容,即响应体 + memset(buff, 0, BUFFLEN); + while ((nCount = fread(buff, 1, BUFFLEN, fp)) > 0) { + write(clnt_sock, buff, nCount); + memset(buff, 0, BUFFLEN); + } + fclose(fp); + shutdown(clnt_sock, SHUT_WR); + read(clnt_sock, buff, sizeof(buff)); + close(clnt_sock); + } + return NULL; +} + +char *http_get_type_by_suffix(const char *suffix) +{ + struct doc_type *type = NULL; + + for (type = file_type; type->suffix; type++) + { + if (strcmp(type->suffix, suffix) == 0) + return type->type; + } + + return NULL; +} + +void http_parse_request_cmd(char *buf,char *file_name, char *suffix) +{ + int file_length = 0, suffix_length = 0; + char *begin=NULL, *end=NULL, *bias=NULL; + + //查找 URL 的开始位置 + begin = strchr(buf, ' '); + begin += 1; + + //查找 URL 的结束位置 + end = strchr(begin, ' '); + *end = 0; + //得到要访问的目标文件(含路径) + file_length = end - begin - 1; + memcpy(file_name, begin+1, file_length); + file_name[file_length] = 0; + //获得文件的后缀名 + bias = strrchr(begin, '/'); + suffix_length = end - bias; + if (*bias == '/') + { + bias++; + suffix_length--; + } + if (suffix_length > 0) + { + begin = strchr(file_name, '.'); + if (begin) + strcpy(suffix, begin + 1); + } +} \ No newline at end of file diff --git a/day5/weak_task/client b/day5/weak_task/client new file mode 100755 index 0000000..07588cb Binary files /dev/null and b/day5/weak_task/client differ diff --git a/day5/weak_task/server b/day5/weak_task/server new file mode 100755 index 0000000..8b83f9c Binary files /dev/null and b/day5/weak_task/server differ diff --git a/day5/weak_task/t5.c b/day5/weak_task/t5.c new file mode 100644 index 0000000..9d0c8b8 --- /dev/null +++ b/day5/weak_task/t5.c @@ -0,0 +1,43 @@ +// a->客户端 +#include +#include +#include +#include +#include +#include + +int main(int argc, char const *argv[]) +{ + int a_fd = socket(AF_INET, SOCK_DGRAM, 0); + if (a_fd < 0) + { + perror("socket"); + return 1; + } + + struct sockaddr_in addr; + bzero(&addr, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(8000); + addr.sin_addr.s_addr = inet_addr("127.0.0.1"); // 服务器在本地 + + while (1) + { + char buf[1] = ""; + bzero(&buf, sizeof(buf)); + scanf("%s", buf); + sendto(a_fd, buf, strlen(buf), 0, (struct sockaddr *)&addr, sizeof(addr)); + + char recvbuf[128] = ""; + socklen_t addr_len = sizeof(addr); + recvfrom(a_fd, recvbuf, strlen(recvbuf), 0, (struct sockaddr *)&addr, &addr_len); + printf("%s", recvbuf); + + if (strncmp(recvbuf, "bye", 3) == 0) + break; + } + + close(a_fd); + + return 0; +} diff --git a/day5/weak_task/t5_a.c b/day5/weak_task/t5_a.c new file mode 100644 index 0000000..f90777e --- /dev/null +++ b/day5/weak_task/t5_a.c @@ -0,0 +1,42 @@ +// a->客户端 +#include +#include +#include +#include +#include +#include + +int main(int argc, char const *argv[]) +{ + int a_fd = socket(AF_INET, SOCK_DGRAM, 0); + if (a_fd < 0) + { + perror("socket"); + return 1; + } + + struct sockaddr_in addr; + bzero(&addr, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(8000); + addr.sin_addr.s_addr = inet_addr("127.0.0.1"); // 服务器在本地 + + while (1) + { + int n = 0; + scanf("%d", &n); + sendto(a_fd, &n, sizeof(n), 0, (struct sockaddr *)&addr, sizeof(addr)); + + char recvbuf[128] = ""; + socklen_t addr_len = sizeof(addr); + recvfrom(a_fd, recvbuf, strlen(recvbuf), 0, (struct sockaddr *)&addr, &addr_len); + printf("%s", recvbuf); + + if (strncmp(recvbuf, "bye", 3) == 0) + break; + } + + close(a_fd); + + return 0; +} diff --git a/day5/weak_task/t5_b.c b/day5/weak_task/t5_b.c new file mode 100644 index 0000000..483ae28 --- /dev/null +++ b/day5/weak_task/t5_b.c @@ -0,0 +1,54 @@ +// b->服务端 +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char const *argv[]) +{ + int b_fd = socket(AF_INET, SOCK_DGRAM, 0); + if (b_fd < 0) + { + perror("socket"); + return 1; + } + + struct sockaddr_in addr; + bzero(&addr, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(8000); + addr.sin_addr.s_addr = htonl(INADDR_ANY); // 接收所有本地ip下同一网段的客户端消息 + // addr.sin_addr.s_addr = inet_addr("127.0.0.1"); + bind(b_fd, (struct sockaddr *)&addr, sizeof(addr)); + + while (1) + { + struct sockaddr_in src_addr; + bzero(&src_addr, sizeof(src_addr)); + socklen_t src_addr_len = sizeof(src_addr); + int n; + socklen_t addr_len = sizeof(addr); + recvfrom(b_fd, &n, sizeof(n), 0, (struct sockaddr *)&src_addr, &src_addr_len); + printf("%d", n); + + char sendbuf[128] = ""; + + if (n == 1) + strcpy(sendbuf, "disen666"); + else if (n == 2) + strcpy(sendbuf, "jack good"); + else if (n == 3) + strcpy(sendbuf, "disen888"); + else if (n == 4) + strcpy(sendbuf, "bye"); + + sendto(b_fd, sendbuf, strlen(sendbuf), 0, (struct sockaddr *)&src_addr, src_addr_len); + } + + close(b_fd); + + return 0; +}