Я устанавливаю сервер-клиентское приложение (чат) и столкнулся с проблемой с сокетами / потоками. И сервер, и клиент работают в Linux.
Я хочу, чтобы сервер мог обслуживать нескольких пользователей, и для этого я хочу использовать потоки из pthread.h , поэтому каждый зарегистрированный пользователь имеет свой собственный поток.
Это сервер :
main.c
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include "manazerUctov.h"
int pocetVlakienZOP = 0;
int main(int argc, char *argv[])
{
pthread_t* vlaknaZiadosti =
(pthread_t*)malloc(sizeof(pthread_t)*POCET_UZIVATELOV);
int sockfd, newsockfd;
socklen_t cli_len;
struct sockaddr_in serv_addr, cli_addr;
int n;
// Program
if (argc < 2) {
fprintf(stderr, "usage %s port\n", argv[0]);
return 1;
}
bzero((char*) &serv_addr, sizeof (serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(atoi(argv[1]));
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
perror("Error creating socket\n");
return 1;
}
printf("Socket OK\n");
if (bind(sockfd, (struct sockaddr*) &serv_addr, sizeof (serv_addr)) < 0) {
perror("Error binding socket address\n");
return 2;
}
printf("Bind OK\n");
listen(sockfd, 5);
while (1) {
cli_len = sizeof (cli_addr);
newsockfd = accept(sockfd, (struct sockaddr*) &cli_addr, &cli_len);
if (newsockfd < 0) {
perror("ERROR on accept\n");
return 3;
}
printf("Accept OK\n");
client_data* cdata = (client_data*) malloc(sizeof (client_data));
cdata->socket = newsockfd;
pthread_t vlakno;
vlaknaZiadosti[pocetVlakienZOP++] = vlakno;
pthread_create(&vlakno, NULL, &serveClient, &cdata);
}
close(sockfd);
return 0;
}
manazerUctov.h
#ifndef MANAZERUCTOV_H
#define MANAZERUCTOV_H
#ifndef POCET_UZIVATELOV
#define POCET_UZIVATELOV 256
#endif
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
char *buffer;
char* msg;
int socket;
} client_data;
void* serveClient(void* pdata);
#ifdef __cplusplus
}
#endif
#endif /* MANAZERUCTOV_H */
manazerUctov.c Здесь функция чтения выдает ошибку:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "manazerUctov.h"
void* serveClient(void *pdata) {
char buffer[256];
client_data* client = (client_data*)pdata;
bzero(buffer, 256);
int n = read(client->socket, buffer, 255);
if (n < 0) {
perror("Error reading from socket\n");
return NULL;
}
printf("Read from socket\n");
close(client->socket);
}
Когда клиент отправляет сокет, сервер принимает его и создает поток, но я получаю Ошибка чтения из сокета: неверный дескриптор файла .
И программа застряла, она даже не выйдет. И, насколько мне известно, розетки еще не закрыты.
До того, как я реализовал потоки, чтение из сокетов работало правильно.
РЕДАКТИРОВАТЬ: Исходный код имеет длину 500 строк, поэтому я обрезал его, и прежней ошибки больше не было, хотя другая ошибка была & cdata в pthread_create . Устранение и устранение проблемы как в усеченном, так и в исходном коде, и сервер работает.