Я пытаюсь войти в сетевое программирование и слежу за руководством по сокетам. Я написал простой Windows TCP-сервер и клиент на C, но не могу заставить их работать. Второй клиент подключается, сервер выдает ошибку «Bad file descriptor» и закрывается. Я не понимаю, как дескриптор файла, который был только что создан accept()
, может быть плохим. Я провел исследование по этому вопросу и нашел людей, которые закрыли файл, прежде чем читать его, чего я не сделал.Ошибка «Bad file descriptor» в принимаемом сокете
Вот код:
SERVER
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
int main(int argc, char *argv[])
{
WSADATA WSAData;
WSAStartup(MAKEWORD(2,0), &WSAData);
SOCKET sock, newsock;
int portno, clilen;
char buffer[256];
SOCKADDR_IN serv_addr, cli_addr;
int n;
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0)
{
perror("Error opening socket");
exit(1);
}
memset((char *) &serv_addr, 0, sizeof(serv_addr));
portno = 5001;
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
if (bind(sock, (SOCKADDR *) &serv_addr, sizeof(serv_addr)) < 0)
{
perror("Eror on binding");
exit(1);
}
listen(sock, 5);
clilen = sizeof(cli_addr);
newsock = accept(sock, (SOCKADDR *) &cli_addr, &clilen);
if (newsock < 0)
{
perror("Error on accept");
exit(1);
}
memset(buffer, 0, 256);
n = read(newsock, buffer, 255);
if (n < 0)
{
perror("Error reading from socket");
exit(1);
}
printf("Here is the message : %s\n", buffer);
n = write(newsock, "I got your message", 18);
if (n < 0)
{
perror("Error writing to socket");
exit(1);
}
WSACleanup();
return 0;
}
КЛИЕНТ
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
int main(int argc, char *argv[])
{
WSADATA WSAData;
WSAStartup(MAKEWORD(2,0), &WSAData);
SOCKET sock;
int portno, n;
SOCKADDR_IN serv_addr;
HOSTENT *server;
char buffer[256];
if (argc < 3)
{
fprintf(stderr, "Usage : %s hostname port\n", argv[0]);
exit(0);
}
portno = atoi(argv[2]);
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0)
{
perror("Error opening socket\n");
exit(1);
}
server = gethostbyname(argv[1]);
if (server == NULL)
{
perror("Error, no such host");
exit(1);
}
memset((char *) &serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
memcpy((char *) &serv_addr.sin_addr.s_addr, (char *) server->h_addr, server->h_length);
serv_addr.sin_port = htons(portno);
if (connect(sock, (SOCKADDR *) &serv_addr, sizeof(serv_addr)) < 0)
{
perror("Error connecting to server");
exit(1);
}
printf("Please enter your message : ");
memset(buffer, 0, 256);
fgets(buffer, 255, stdin);
n = write(sock, buffer, strlen(buffer));
if (n < 0)
{
perror("Error writing to socket");
exit(1);
}
memset(buffer, 0, 256);
n = read(sock, buffer, 255);
if (n < 0)
{
perror("Error reading from socket");
exit(1);
}
printf("%s\n", buffer);
WSACleanup();
return 0;
}
... А вот выход только в случае, если:
C:\...myfolder>server
*here it does nothing until I start the client with "client 127.0.0.1 5001" in another window*
Error reading from socket: Bad file descriptor
вы видите что не так с моей треской е? Заранее спасибо за вашу помощь!
Спасибо, сейчас работает! Означает ли это, что API сокетов Windows не реализован так же, как и Linux-сокеты? Как и в, мои переменные сокета действительно файловые дескрипторы или просто идентификатор, специально предназначенный для winsock? – Toctave
Является ли что-либо * действительно файловым дескриптором в Windows, или все это просто куча клоджей, притворяющаяся файловым дескриптором? –
У вас есть точка. Но тогда все эти клоды являются одним и тем же типом kludge? Являются ли 'sock' и' stdin' одинаковыми, и если не так, как они отличаются? – Toctave