20221320—冯泰瑞—课上测试:网络编程

news/2025/2/2 20:17:10/文章来源:https://www.cnblogs.com/feng-tairui/p/18697049

20221320—冯泰瑞—课上测试:网络编程

完成下面任务(29分)

1.在 Ubuntu 或 openEuler 中完成任务(推荐openEuler)

2.参考《head first C》实现knock knock服务器,提交代码knock.c,编译运行过程(13分)

服务器

fengtairui@fengtairui-virtual-machine:~$ touch knock.c
fengtairui@fengtairui-virtual-machine:~$ vim knock.c
fengtairui@fengtairui-virtual-machine:~$ gcc -o knock knock.c
fengtairui@fengtairui-virtual-machine:~$ ./knock
Knock Knock server is running on port 8080...

客户端

fengtairui@fengtairui-virtual-machine:~$ telnet localhost 8080
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Knock! Knock!
Who's there?
Lettuce.
Lettuce who?
Lettuce in, it's cold out here!

代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>#define PORT 8080
#define BUFFER_SIZE 1024void handle_client(int client_socket) {char buffer[BUFFER_SIZE];int read_size;// 发送初始消息send(client_socket, "Knock! Knock!\n", strlen("Knock! Knock!\n"), 0);// 等待客户端的响应read_size = recv(client_socket, buffer, BUFFER_SIZE, 0);buffer[read_size] = '\0'; // 确保字符串以 null 结尾if (strcmp(buffer, "Who's there?\n") == 0) {send(client_socket, "Lettuce.\n", strlen("Lettuce.\n"), 0);read_size = recv(client_socket, buffer, BUFFER_SIZE, 0);buffer[read_size] = '\0';if (strcmp(buffer, "Lettuce who?\n") == 0) {send(client_socket, "Lettuce in, it's cold out here!\n", strlen("Lettuce in, it's cold out here!\n"), 0);} else {send(client_socket, "I didn't get that.\n", strlen("I didn't get that.\n"), 0);}} else {send(client_socket, "I didn't get that.\n", strlen("I didn't get that.\n"), 0);}close(client_socket);
}int main() {int server_socket, client_socket;struct sockaddr_in server_addr, client_addr;socklen_t addr_size;// 创建 socketserver_socket = socket(AF_INET, SOCK_STREAM, 0);if (server_socket < 0) {perror("Socket creation failed");exit(EXIT_FAILURE);}// 配置服务器地址server_addr.sin_family = AF_INET;server_addr.sin_addr.s_addr = INADDR_ANY;server_addr.sin_port = htons(PORT);// 绑定 socketif (bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {perror("Bind failed");close(server_socket);exit(EXIT_FAILURE);}// 监听连接if (listen(server_socket, 5) < 0) {perror("Listen failed");close(server_socket);exit(EXIT_FAILURE);}printf("Knock Knock server is running on port %d...\n", PORT);// 接受客户端连接while (1) {addr_size = sizeof(client_addr);client_socket = accept(server_socket, (struct sockaddr*)&client_addr, &addr_size);if (client_socket < 0) {perror("Accept failed");continue;}// 处理客户端handle_client(client_socket);}// 关闭服务器 socketclose(server_socket);return 0;
}

3.使用多线程实现knock knock服务器,提交代码knockmt.c,编译运行过程,至少两个客户端测试,服务器运行结果中要打印线程id(13分)

服务器

fengtairui@fengairui-virtual-machine:~$ touch knockmt.c
fengtairui@fengtairui-virtual-machine:~$ vim knockmt.c
fengtairui@fengtairui-virtual-machine:~$ gcc knockmt.c -o knockmt -lpthread
fengtairui@fengtairui-virtual-machine:~$ ./knockmt
Knock knock server is listening on port 8088...
Accepted connection from 127.0.0.1:55206
Thread ID: 123637524858432 is handling client connection
Accepted connection from 127.0.0.1:57026
Thread ID: 123637514372672 is handling client connection

客户端1

fengtairui@fengtairui-virtual-machine:~$ telnet localhost 8088
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Knock knock
Who's there?
Omar
Omar who?
Omar my goodness, you scared me!
Haha, that's a good one! Come on in.

客户端2

fengtairui@fengtairui-virtual-machine:~$ telnet localhost 8088
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Knock
You didn't say 'Knock knock'. Goodbye.

代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <pthread.h>#define PORT 8088
#define MAX_BUFFER_SIZE 1024// 结构体用于传递参数给线程函数
typedef struct {int clientSocket;struct sockaddr_in clientAddr;
} ThreadArgs;// 处理客户端连接的线程函数
void *handleClientThread(void *arg) {ThreadArgs *args = (ThreadArgs *)arg;int clientSocket = args->clientSocket;struct sockaddr_in clientAddr = args->clientAddr;char buffer[MAX_BUFFER_SIZE];int n;// 获取线程IDpthread_t tid = pthread_self();printf("Thread ID: %lu is handling client connection\n", tid);// 接收客户端消息n = read(clientSocket, buffer, MAX_BUFFER_SIZE);if (n < 0) {perror("Error reading from socket");close(clientSocket);free(arg);pthread_exit(NULL);}buffer[n] = '\0';// 检查消息是否为"Knock knock"if (strcmp(buffer, "Knock knock") == 0) {const char *response1 = "Who's there?";write(clientSocket, response1, strlen(response1));// 接收客户端下一条消息n = read(clientSocket, buffer, MAX_BUFFER_SIZE);if (n < 0) {perror("Error reading from socket");close(clientSocket);free(arg);pthread_exit(NULL);}buffer[n] = '\0';// 检查消息是否为"Omar"if (strcmp(buffer, "Omar") == 0) {const char *response2 = "Omar who?";write(clientSocket, response2, strlen(response2));// 接收客户端最后一条消息n = read(clientSocket, buffer, MAX_BUFFER_SIZE);if (n < 0) {perror("Error reading from socket");close(clientSocket);free(arg);pthread_exit(NULL);}buffer[n] = '\0';// 检查消息是否为"Omar my goodness, you scared me!"if (strcmp(buffer, "Omar my goodness, you scared me!") == 0) {const char *response3 = "Haha, that's a good one! Come on in.";write(clientSocket, response3, strlen(response3));} else {const char *response3 = "I don't understand. Goodbye.";write(clientSocket, response3, strlen(response3));}} else {const char *response2 = "I don't know who that is. Goodbye.";write(clientSocket, response2, strlen(response2));}} else {const char *response = "You didn't say 'Knock knock'. Goodbye.";write(clientSocket, response, strlen(response));}close(clientSocket);free(arg);pthread_exit(NULL);
}int main() {int serverSocket, clientSocket;struct sockaddr_in serverAddr, clientAddr;socklen_t clientAddrLen = sizeof(clientAddr);pthread_t thread;// 创建套接字serverSocket = socket(AF_INET, SOCK_STREAM, 0);if (serverSocket < 0) {perror("Error creating socket");exit(1);}// 初始化服务器地址结构memset(&serverAddr, 0, sizeof(serverAddr));serverAddr.sin_family = AF_INET;serverAddr.sin_addr.s_addr = INADDR_ANY;serverAddr.sin_port = htons(PORT);// 绑定套接字到指定地址和端口if (bind(serverSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0) {perror("Error binding socket");exit(1);}// 监听连接请求if (listen(serverSocket, 5) < 0) {perror("Error listening for connections");exit(1);}printf("Knock knock server is listening on port %d...\n", PORT);while (1) {// 接受客户端连接clientSocket = accept(serverSocket, (struct sockaddr *)&clientAddr, &clientAddrLen);if (clientSocket < 0) {perror("Error accepting connection");continue;}// 获取客户端IP地址char clientIP[INET_ADDRSTRLEN];inet_ntop(AF_INET, &clientAddr.sin_addr, clientIP, INET_ADDRSTRLEN);printf("Accepted connection from %s:%d\n", clientIP, ntohs(clientAddr.sin_port));// 为每个客户端连接创建一个新线程ThreadArgs *args = (ThreadArgs *)malloc(sizeof(ThreadArgs));args->clientSocket = clientSocket;args->clientAddr = clientAddr;if (pthread_create(&thread, NULL, handleClientThread, (void *)args)!= 0) {perror("Error creating thread");close(clientSocket);free(args);continue;}// 分离线程,使其在结束后自动释放资源pthread_detach(thread);}close(serverSocket);return 0;
}

4.提交git log结果(3分)

fengtairui@fengtairui-virtual-machine:~$ git add knock.c knockmt.c knock knockmt
fengtairui@fengtairui-virtual-machine:~$ git commit -m "konck"
[master 0027bef] konck4 files changed, 220 insertions(+)create mode 100755 knockcreate mode 100644 knock.ccreate mode 100755 knockmtcreate mode 100644 knockmt.c
fengtairui@fengtairui-virtual-machine:~$ git log
commit 0027bef181c7570899f2918eb52ed4f8cbc6041c (HEAD -> master)
Author: fengtairui <1978274655@qq.com>
Date:   Tue Dec 17 10:58:53 2024 +0800konck

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/878088.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ollama mac使用

教程地址:https://www.youtube.com/watch?v=SRroLOci0CA 安装完成后,常用命令。 启动服务:ollama run deepseek-r1:8B 使用:停止服务:本文来自博客园,作者:NeverLateThanBetter,转载请注明原文链接:https://www.cnblogs.com/do-it-520/p/18697037韶华易逝,不能虚度年…

07. 文件操作

一、文件的查找我们可以使用 find 命令 从指定目录向下递归地遍历其各个子目录,将满足的文件显示在终端中。 find [搜索范围] [选项]其中,选项的可选值如下:-name 文件名:按照指定的文件名查找文件,如果不知道文件的全名,可以使用 * 进行模糊匹配。 -user 用户名:查找属…

《计算机网络》笔记——第五章 运输层

计算机网络(第7版)谢希仁目录第5章 运输层概述运输层的两个主要协议端口用户数据报协议UDPUDP的首部格式传输控制协议TCPTCP的连接可靠传输的工作原理停止等待协议连续ARQ协议TCP报文段的首部格式TCP可靠传输的实现滑动窗口超时重传时间(RTO)的选择选择确认SACKTCP的流量控制…

[Paper Reading] DeepSeek-V3 Technical Report

目录DeepSeek-V3 Technical Report解读TL;DR优势训练数据参数量Method架构MLA(Multi-Head Latent Attention)DeepSeekMoEMoEDeepSeekMoEMTP(Multi-Token Prediction)基建FP8训练部署PrefillingDecodingPre-TrainingDataLong Context ExtensionPost-TrainingSFTReinforcement Le…

表单标签3

如何点击用户名来唤醒对应光标 中for id 两者的对象一致

省选模拟4

省选模拟4 A 小丑做法,设 \(f_{S,i,j}\) 为使用边权 \(\le j\) 的边连通了集合 \(S\),里面使用了 \(i\) 个 \(a\) 的最小生成树。 转移朴素枚举,复杂度 \(O(3^nm^3)\) B 是原题。 注意到一个点走过一轮后,从父亲离开后下一次访问会完全访问。 因此可以 dfs 求得一个节点会在…

闲话 25.2.2

the Kernel Method: a collection of examples 读后感闲话 我怎么感觉我读了这个论文,还不知道 kernel method 是啥啊。 没人总结这个,可能未来要读一些新东西。 推歌:时间的彼端 by 暗猫の祝福 et al. the Kernel Method: a collection of examples 读后感 \(1.\) 第一次出…

表单标签

表单就是数据采集,QQ登录页面类似 定义表单 action:规定提交列表式向何处发送表单数据 method:规定用于发送表单数据方式 action="#"时将表单数据提交到当前的html页面

CTFShow-Web160:利用日志包含漏洞进行文件上传

CTFShow-Web160:利用日志包含漏洞进行文件上传 过滤规则 该题对上传文件内容的过滤规则如下: ​ • 禁止包含 空格 ​ • 禁止包含 反引号 (``) ​ • 禁止包含 log 由于反引号被过滤,无法使用 Web159 的方法,需要利用 日志包含漏洞 来实现绕过。 日志包含漏洞原理 日志包含…

关于在使用VSCode编译C++文件时,显示c++11以上的函数或者方法报错,但是能编译通过的可能解决办法之一

在此之前:已经下载好mingw64,并且将bin目录配置到系统变量当中。第一步,在对应文件当中按住Ctrl + Shift + p,再输入c++,显示出如下内容:点击编辑配置 如果你以前下载过VS,那么这里可能默认为CL.exe(推测:这就是我为什么会出现这个错误的原因),将其改为对应目录下g+…

ADALM-Pluto修改IP地址

在 GNURadio 中使用 ADALM-Pluto 模块是以 IP 地址为基础进行通信的,而固定的 IP 地址 192168.2.1 导致一台电脑无法使用多个 Pluto,因此应该进行更改。在 GNURadio 中使用 ADALM-Pluto 模块是以 IP 地址为基础进行通信的,而固定的 IP 地址 192168.2.1 导致一台电脑无法使用…