#c #client-server
#c #клиент-сервер
Вопрос:
Я пишу простое клиент-серверное приложение, и у меня возникают проблемы с тем, чтобы заставить клиента непрерывно отвечать на отправленные ему сообщения (на данный момент, echo).
client.c
#define BUF_SIZE 1024
int ctrlsockfd;
void error(const char *message);
void closeStreams();
void writeResponse(const char *message);
int main (int argc, const char *argv[]) {
printf("Clientn");
// Connection code snipped
// Handle responses
int bytes_read;
char buffer[BUF_SIZE];
while (1) {
// Fetch a message
bytes_read = read(ctrlsockfd, buffer, BUF_SIZE);
if (bytes_read == -1) {
error("Failed to read");
}
// Send it back
if (write(ctrlsockfd, buffer, strlen(buffer) 1) == -1) {
error("Failed to write");
}
}
// Disconnect
closeStreams();
return 0;
}
host.c
#define BUF_SIZE 1024
#define LISTENPORT 9735
void closeStreams();
void error(const char *message);
int ctrlsockfd, clientsockfd;
int main (int argc, const char *argv[]) {
printf("Servern");
// Connection code snipped
// Accept a request (blocking) - we can only connect to one client at a time
clientlen = sizeof(clientaddr);
clientsockfd = accept(ctrlsockfd, (struct sockaddr *) amp;clientaddr, (socklen_t*) amp;clientlen);
if (clientsockfd == -1) {
error("Error accepting");
}
while (1) {
// Read input string from stdin
printf("> ");
char message[BUF_SIZE];
if (scanf("%s", message) == -1) {
error("Failed to read from terminal");
}
// Send to client
if (write(clientsockfd, message, strlen(message) 1) == -1) {
error("Failed to send message");
} else {
printf("Sent message %sn", message);
}
// Read response from client
char response[BUF_SIZE];
if (read(clientsockfd, response, BUF_SIZE) == -1) {
error("Error reading response");
} else {
printf("Response: %sn", response);
}
// Close the connection
closeStreams();
}
}
В чем здесь проблема?
Ответ №1:
Я думаю, вы путаете сервер и клиент здесь. Обычно сервер прослушивает порт и ожидает сообщений, а затем отвечает на них. Кроме того, accept() должен быть частью цикла, если вы закрываете соединение на каждой итерации или, альтернативно, не закрываете соединение.
Server client
wait
connect
send data
read data
send data
read data
<maybe iteration of send / receive here >
close close
wait
...
Комментарии:
1. Да, в моем случае мне нужно поменять роли местами, чтобы вы могли просто поменять имена — мне также нужно слушать запросы только одного клиента.
2. @Ross — хорошо, все же обратите внимание, что вы по какой-то причине закрываете соединение в конце цикла работы сервера, если вы хотите продолжить отправку данных, вам не следует закрывать соединение.
3. Ах, вот в чем была проблема — спасибо за вашу помощь (и по другому вопросу)!
Ответ №2:
Здесь немного больше ошибок, но я бы сразу сделал это:
// Send it back
if (bytes_read > 0 amp;amp; write(ctrlsockfd, buffer, strlen(buffer) 1) == -1) {
error("Failed to write");
}
Любопытно, что делали эти записи, когда ничего не было прочитано…
Комментарии:
1. О, понятно, извините, я не подумал об этом должным образом — я предполагал, что read будет блокироваться до тех пор, пока не будут прочитаны байты.
2. Я не знаю, какая у вас точная среда, но в какой-то момент при чтении сокета наступает тайм-аут и возвращается ошибка тайм-аута.
3. Есть ли способ предотвратить это (т. Е. Без тайм-аута) или лучший шаблон, который я должен использовать?