【无标题】

1 在 Ubuntu 或 openEuler 中完成任务(推荐openEuler)
2 参考《head first C》实现knock knock服务器,提交代码knock.c,编译运行过程(13分)
3 使用多线程实现knock knock服务器,提交代码knockmt.c,编译运行过程,至少两个客户端测试,服务器运行结果中要打印线程id(13分)
4 提交git log结果(3分)
c
// knock.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

int main() {
char buffer[256];
int should_continue = 1;

while (should_continue) {
    printf("Knock knock\n");
    fflush(stdout); // 确保输出被立即发送

    if (fgets(buffer, 256, stdin) == NULL) {
        perror("Error reading from stdin");
        exit(EXIT_FAILURE);
    }

    if (strcmp(buffer, "Who's there?\n") == 0) {
        printf("Computer\n");
        fflush(stdout);
        if (fgets(buffer, 256, stdin) == NULL) {
            perror("Error reading from stdin");
            exit(EXIT_FAILURE);
        }
        if (strcmp(buffer, "Computer who?\n") == 0) {
            printf("Computer says boot and listen.\n");
            fflush(stdout);
            if (fgets(buffer, 256, stdin) == NULL) {
                perror("Error reading from stdin");
                exit(EXIT_FAILURE);
            }
            if (strcmp(buffer, "I don't get it.\n") == 0) {
                printf("I know you don't get it. That's why I'm explaining it.\n");
                fflush(stdout);
                should_continue = 0;
            }
        }
    } else {
        printf("Who's there?\n");
        fflush(stdout);
    }
}

return 0;

}
编译运行过程:

bash
gcc -o knock knock.c
./knock
3. 使用多线程实现 Knock Knock 服务器
以下是使用多线程实现的 Knock Knock 服务器的代码示例:

c
// knockmt.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>

#define BUFFER_SIZE 256

void *handle_client(void *socket_desc) {
char buffer[BUFFER_SIZE];
long socket = (long)socket_desc;
pthread_t thread_id = pthread_self();

printf("Thread %ld handling client %ld\n", thread_id, socket);

if (read(socket, buffer, BUFFER_SIZE) > 0) {
    if (strcmp(buffer, "Knock knock\n") == 0) {
        write(socket, "Who's there?\n", 14);
    } else if (strcmp(buffer, "Who's there?\n") == 0) {
        write(socket, "Computer\n", 8);
    } else if (strcmp(buffer, "Computer who?\n") == 0) {
        write(socket, "Computer says boot and listen.\n", 28);
    } else if (strcmp(buffer, "I don't get it.\n") == 0) {
        write(socket, "I know you don't get it. That's why I'm explaining it.\n", 45);
    } else {
        write(socket, "Sorry, I don't understand.\n", 24);
    }
}

close(socket);
free(socket_desc);
pthread_exit(NULL);

}

int main() {
int server_fd, new_socket;
struct sockaddr_in address;
int opt = 1;
int addrlen = sizeof(address);
pthread_t tid;

// Creating socket file descriptor
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
    perror("socket failed");
    exit(EXIT_FAILURE);
}

// Forcefully attaching socket to the port 8080
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {
    perror("setsockopt");
    exit(EXIT_FAILURE);
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(8080);

// Forcefully attaching socket to the port 8080
if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
    perror("bind failed");
    exit(EXIT_FAILURE);
}
if (listen(server_fd, 3) < 0) {
    perror("listen");
    exit(EXIT_FAILURE);
}

printf("Listening on port 8080...\n");

while (1) {
    if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {
        perror("accept");
        exit(EXIT_FAILURE);
    }

    int *new_sock = malloc(1);
    *new_sock = new_socket;

    if (pthread_create(&tid, NULL, handle_client, (void *)new_sock) != 0) {
        perror("could not create thread");
    }
}

return 0;

}
编译运行过程:

gcc -o knockmt knockmt.c -lpthread
./knockmt
客户端测试:

telnet localhost 8080

Trying 127.0.0.1…
Connected to localhost.
Escape character is ‘^]’.
Knock knock
Who’s there?
Who’s there?
Computer
Computer who?
Computer says boot and listen.
I don’t get it.
I know you don’t get it. That’s why I’m explaining it.
Connection closed by foreign host.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值