gpt4 book ai didi

c - Unix 服务器 : Reading Thread behaves faulty

转载 作者:行者123 更新时间:2023-11-30 19:01:52 25 4
gpt4 key购买 nike

我已经编写了一个服务器,它应该是一个终端聊天应用程序(仅用于练习)。为了读取传入的消息,我为每个客户端创建了一个线程,其唯一目的是读取传入的文本...

但是,这个函数似乎执行以下操作:如果终端输入/输出为空,服务器打印:“客户端[消息]”而不将其发送回其他客户端。但是,如果终端输入/输出不为空,则会发回数据,但不打印:“Client [message]”。我无法完全理解这个错误。此外,当客户端断开连接时,服务器将退出。

这是服务器:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <pthread.h>

#define BUFLEN 255
#define MAX_CONNECTIONS 128
#define TRUE 1
#define FALSE 0

void* job_read(void * p);
void* job_write(void*);

//Global Variables
FILE* plogfile;
int socket_ids[MAX_CONNECTIONS];
char endprogramm = FALSE;
int open_cnncts = 0;
pthread_mutex_t mutex;

void error(const char* msg){
perror(msg);
exit(1);
}

int main(int argc, char* argv[]) {
if(argc < 2){
fprintf(stderr, "You must provide a port number");
exit(EXIT_FAILURE);
}
if(argc == 3){
plogfile = fopen(argv[2], "w");
} else {
plogfile = fopen("logfile.txt", "w");
}
stderr = plogfile;
int sockfd, portnum;

//Create nmutthread
if(pthread_mutex_init(&mutex, NULL)<0){
error("Could not initialize Mutex");
}
//Initialzing threads and create writethread
pthread_t readthreads[MAX_CONNECTIONS];
pthread_t writethread;
pthread_create(&writethread, NULL, job_write, NULL);

//Setup for connections
struct sockaddr_in serv_add, cli_adr;
socklen_t clilen;
clilen = sizeof(cli_adr);
bzero((char*)&serv_add, sizeof(struct sockaddr_in));

portnum = atoi(argv[1]);
serv_add.sin_family = AF_INET;
serv_add.sin_addr.s_addr = INADDR_ANY;
serv_add.sin_port = htons(portnum);

sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd < 0){
error("Error opening socket.");
}

//Bind listening
if(bind(sockfd, (struct sockaddr*) (&serv_add), sizeof(serv_add)) < 0){
error("Binding failed.");
}
for(open_cnncts = 0; (!endprogramm) & (open_cnncts < MAX_CONNECTIONS); open_cnncts++){
fprintf(plogfile,"Listening....");
listen(sockfd, MAX_CONNECTIONS);
socket_ids[open_cnncts] = accept(sockfd, (struct sockaddr*) &cli_adr, &clilen);
fprintf(plogfile,"Client connected.\n");
pthread_create(&readthreads[open_cnncts] , NULL, job_read, (void*)&socket_ids[open_cnncts]);
}
endprogramm = TRUE;
close(sockfd);
for(; open_cnncts != 0; open_cnncts--){
close(socket_ids[open_cnncts]);
pthread_join(readthreads[open_cnncts], NULL);
}
pthread_join(writethread, NULL);
pthread_mutex_destroy(&mutex);
return 0;

}

void* job_read(void * p){
int* socketp = (int*)p;
int newsockfd = (*socketp);
size_t n;
char buffer[BUFLEN];
while(!endprogramm){
bzero(buffer, BUFLEN);
n = read(newsockfd, buffer, BUFLEN);
if(n){
error("Reading Failed");
}
pthread_mutex_lock(&mutex);
for(int i = 0; i < open_cnncts; i++){
if(socket_ids[i] == newsockfd)continue;
n = write(socket_ids[i], buffer, strlen(buffer));
if(n < 0){
error("Writing failed");
}
}
pthread_mutex_unlock(&mutex);
printf("Client: %s\n", buffer);
}
return NULL;
}

void* job_write(void* args){
fprintf(plogfile, "Started writing thread...\n");
size_t n;
char buffer[BUFLEN];
while(!endprogramm) {
bzero(buffer, BUFLEN);
fgets(buffer, BUFLEN, stdin);

pthread_mutex_lock(&mutex);
for(int i = 0; i < open_cnncts; i++){
n = write(socket_ids[i], buffer, strlen(buffer));
if(n < 0){
error("Writing failed");
}
}
pthread_mutex_unlock(&mutex);
if(strcmp("Bye", buffer) == 0){
break;
}
}
endprogramm = TRUE;
return NULL;
}

我认为错误就在这里:

void* job_write(void* args){
fprintf(plogfile, "Started writing thread...\n");
size_t n;
char buffer[BUFLEN];
while(!endprogramm) {
bzero(buffer, BUFLEN);
fgets(buffer, BUFLEN, stdin);

pthread_mutex_lock(&mutex);
for(int i = 0; i < open_cnncts; i++){
n = write(socket_ids[i], buffer, strlen(buffer));
if(n < 0){
error("Writing failed");
}
}
pthread_mutex_unlock(&mutex);
if(strcmp("Bye", buffer) == 0){
break;
}
}
endprogramm = TRUE;
return NULL;
}

这里是终端的输入:

Terminal 1:
./Server 9999
...
Client: "Hello"
...
...


Terminal 2:
./Client 127.0.0.1 9999
Hello
...
Hello
Server: Hello

如果您想重现该错误,这是客户的代码:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <pthread.h>

#define BUFLEN 255
#define TRUE 1
#define FALSE 0

char endprogram = 0;
int sockfd;


void error(const char* msg){
perror(msg);
exit(1);
}

void* job_read(void* p){
char buffer[BUFLEN];
while(!endprogram){
bzero(buffer, BUFLEN);
size_t n = read(sockfd, buffer, (BUFLEN));
if(n < 0){
error("Error on reading");
}
printf("Server: %s", buffer);
int i = strncmp("Bye", buffer, 3);
if(i == 0){
endprogram = TRUE;
return NULL;
}
}
return NULL;
}

int main(int argc, const char * argv[]) {
pthread_t readt;

int sockfd, portnum;
struct sockaddr_in serveraddr;
struct hostent* server;

if(argc < 3){
perror("You shall provide a port and a ip adress");
}
portnum = atoi(argv[2]);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd < 0){
error("Error opening socket");
}

server = gethostbyname(argv[1]);
if(!server){
error("No such host");
}

bzero((char*)&serveraddr, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
bcopy((char *)server->h_addr, (char *)&serveraddr.sin_addr.s_addr, sizeof(server->h_length));
serveraddr.sin_port = htons(portnum);

if(connect(sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr))<0){
error("Connection failed");
}

pthread_create(&readt, NULL, &job_read, NULL);

size_t n;
char buffer[BUFLEN];
while(!endprogram){
bzero(buffer, BUFLEN);
fgets(buffer, BUFLEN, stdin);
n = write(sockfd, buffer, strlen(buffer));
if(n < 0){
error("Error on writing");
}
n = strcmp(buffer, "Bye");
if(n == 0){
endprogram = TRUE;
}
}
pthread_join(readt, NULL);
close(sockfd);
return 0;
}

编辑:服务器应该打印客户端的消息并将其写回所有其他客户端...

编辑编辑:

我希望这段代码更适合您编译和阅读:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <pthread.h>
#include <stdbool.h>

#define BUFLEN 255
#define MAX_CONNECTIONS 128


void* job_read(void * p);
void* job_write(void*);

//Global Variables
FILE* plogfile;
int socket_ids[MAX_CONNECTIONS];
bool endprogramm = false;
int open_cnncts = 0;
pthread_mutex_t mutex;

void error(const char* msg){
perror(msg);
exit(1);
}

int main(int argc, char* argv[]) {
if(argc < 2){
fprintf(stderr, "You must provide a port number");
exit(EXIT_FAILURE);
}
if(argc == 3){
plogfile = fopen(argv[2], "w");
} else {
plogfile = fopen("logfile.txt", "w");
}
stderr = plogfile;
int sockfd;
uint16_t portnum;

//Create nmutthread
if(pthread_mutex_init(&mutex, NULL)<0){
error("Could not initialize Mutex");
}
//Initialzing threads and create writethread
pthread_t readthreads[MAX_CONNECTIONS];
pthread_t writethread;
pthread_create(&writethread, NULL, job_write, NULL);

//Setup for connections
struct sockaddr_in serv_add;
struct sockaddr_in cli_adr;
socklen_t clilen;
clilen = sizeof(cli_adr);
bzero((char*)&serv_add, sizeof(struct sockaddr_in));

portnum = (uint16_t)atoi(argv[1]);
serv_add.sin_family = AF_INET;
serv_add.sin_addr.s_addr = INADDR_ANY;
serv_add.sin_port = htons(portnum);

sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd < 0){
error("Error opening socket.");
}

//Bind listening
if(bind(sockfd, (struct sockaddr*) (&serv_add), sizeof(serv_add)) < 0){
error("Binding failed.");
}
for(open_cnncts = 0; (!endprogramm) & (open_cnncts < MAX_CONNECTIONS); open_cnncts++){
fprintf(plogfile,"Listening....");
listen(sockfd, MAX_CONNECTIONS);
socket_ids[open_cnncts] = accept(sockfd, (struct sockaddr*) &cli_adr, &clilen);
fprintf(plogfile,"Client connected.\n");
pthread_create(&readthreads[open_cnncts] , NULL, job_read, (void*)&socket_ids[open_cnncts]);
}
endprogramm = true;
close(sockfd);
for(; open_cnncts != 0; open_cnncts--){
close(socket_ids[open_cnncts]);
pthread_join(readthreads[open_cnncts], NULL);
}
pthread_join(writethread, NULL);
pthread_mutex_destroy(&mutex);
return 0;

}

void* job_read(void * p){
int* socketp = (int*)p;
int newsockfd = (*socketp);
ssize_t n;
char buffer[BUFLEN];
while(!endprogramm){
bzero(buffer, BUFLEN);
n = read(newsockfd, buffer, BUFLEN);
if(n){
error("Reading Failed");
}
pthread_mutex_lock(&mutex);
for(int i = 0; i < open_cnncts; i++){
if(socket_ids[i] == newsockfd){
continue;
}
n = write(socket_ids[i], buffer, strlen(buffer));
if(n < 0){
error("Writing failed");
}
}
pthread_mutex_unlock(&mutex);
printf("Client: %s\n", buffer);
}
pthread_exit( NULL );
}

void* job_write(void* args){
(void)args;
fprintf(plogfile, "Started writing thread...\n");
ssize_t n;
char buffer[BUFLEN];
while(!endprogramm) {
fgets(buffer, BUFLEN, stdin);

pthread_mutex_lock(&mutex);
for(int i = 0; i < open_cnncts; i++){
n = write(socket_ids[i], buffer, strlen(buffer));
if(n < 0){
error("Writing failed");
}
}
pthread_mutex_unlock(&mutex);
if(strcmp("Bye", buffer) == 0){
break;
}
}
endprogramm = true;
pthread_exit( NULL );
}

客户:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <pthread.h>
#include <stdbool.h>

#define BUFLEN 255


bool endprogram = false;
int sockfd;


void error(const char* msg){
perror(msg);
exit(1);
}

void* job_read(void* p){
(void)p;
char buffer[BUFLEN];
while(!endprogram){
bzero(buffer, BUFLEN);
size_t n = read(sockfd, buffer, (BUFLEN));
if(n < 0){
error("Error on reading");
}
printf("Server: %s", buffer);
int i = strncmp("Bye", buffer, 3);
if(i == 0){
endprogram = true;
return NULL;
}
}
return NULL;
}

int main(int argc, const char * argv[]) {
pthread_t readt;

int sockfd;
int16_t portnum;
struct sockaddr_in serveraddr;
struct hostent* server;

if(argc < 3){
perror("You shall provide a port and a ip adress");
}
portnum = atoi(argv[2]);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd < 0){
error("Error opening socket");
}

server = gethostbyname(argv[1]);
if(!server){
error("No such host");
}

bzero((char*)&serveraddr, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
bcopy((char *)server->h_addr, (char *)&serveraddr.sin_addr.s_addr, sizeof(server->h_length));
serveraddr.sin_port = htons(portnum);

if(connect(sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr))<0){
error("Connection failed");
}

pthread_create(&readt, NULL, &job_read, NULL);

ssize_t n;
char buffer[BUFLEN];
while(!endprogram){
fgets(buffer, BUFLEN, stdin);
n = write(sockfd, buffer, strlen(buffer));
if(n < 0){
error("Error on writing");
}
n = strcmp(buffer, "Bye");
if(n == 0){
endprogram = false;
}
}
pthread_join(readt, NULL);
close(sockfd);
return 0;
}

编辑编辑编辑:

我得到的错误是在阅读线程中:“错误阅读:未定义错误”。如果我使用 xCode 启动服务器,则服务器似乎会在不编写控制台的情况下多次崩溃。

已知错误:

  • 如果客户端断开连接,线程和文件描述符?

最佳答案

发布的代码无法完全编译!

以下列出了主要问题。

编译时,始终启用警告,然后修复这些警告。

对于gcc,至少使用:-Wall -Wextra -Wconversion -pedantic -std=gnu11

注意:其他编译器使用不同的选项来执行相同的操作。

untitled.c: In function ‘main’:
untitled.c:61:31: warning: conversion to ‘uint16_t {aka short unsigned int}’ from ‘int’ may alter its value [-Wconversion]
serv_add.sin_port = htons(portnum);
^~~~~~~

untitled.c: In function ‘job_read’:
untitled.c:98:13: warning: conversion to ‘size_t {aka long unsigned int}’ from ‘ssize_t {aka long int}’ may change the sign of the result [-Wsign-conversion]
n = read(newsockfd, buffer, BUFLEN);
^~~~

untitled.c:105:17: warning: conversion to ‘size_t {aka long unsigned int}’ from ‘ssize_t {aka long int}’ may change the sign of the result [-Wsign-conversion]
n = write(socket_ids[i], buffer, strlen(buffer));
^~~~~

untitled.c:106:18: warning: comparison of unsigned expression < 0 is always false [-Wtype-limits]
if(n < 0){
^

untitled.c: In function ‘job_write’:
untitled.c:126:17: warning: conversion to ‘size_t {aka long unsigned int}’ from ‘ssize_t {aka long int}’ may change the sign of the result [-Wsign-conversion]
n = write(socket_ids[i], buffer, strlen(buffer));
^~~~~

untitled.c:127:18: warning: comparison of unsigned expression < 0 is always false [-Wtype-limits]
if(n < 0){
^

untitled.c:116:23: warning: unused parameter ‘args’ [-Wunused-parameter]
void* job_write(void* args){

一旦您干净地编译了代码,请更新(添加编辑),我们可以帮助您

关于c - Unix 服务器 : Reading Thread behaves faulty,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57028260/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com