Ошибка «отказано в соединении» означает, что вы пытаетесь подключиться к IP-адресу сервера: порт:
не открыт для прослушивания
имеет слишком много ожидающих клиентских подключений в своем бэклоге
, заблокированных брандмауэром / маршрутизатором / антивирусом.
Невозможно подключитьсяклиентская сторона, чтобы определить, какое условие вызывает ошибку.Все, что он может сделать, это повторить попытку позже и через некоторое время сдаться.
Поскольку ваш клиент пытается подключиться к 127.0.0.1
, клиент и сервер ДОЛЖНЫ работать на одном компьютере.Вы не сможете подключиться через границы компьютера, включая границы виртуальных машин между системами хост / клиент.
При этом я вижу ряд ошибок в вашем коде, но ни одной из них, вызывающих ошибку подключения..
Сторона сервера:
socket()
возвращает -1 при ошибке, а не 0.
//if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0){
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
youнельзя установить несколько параметров сокетов одновременно с setsockopt()
, вы должны установить их индивидуально с отдельными вызовами на setsockopt()
.
//setsockopt(server_fd , SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt));
setsockopt(server_fd , SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
setsockopt(server_fd , SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt));
Сторона клиента:
вы заполняете serv_addr
'0'
символами вместо 0
байтов.
//memset(&serv_addr , '0' , sizeof(serv_addr));
memset(&serv_addr, 0, sizeof(serv_addr));
С обеих сторон вы не делаете никакихобработка ошибок на send()
.Но что более важно, вы не включаете нулевой терминатор сообщения в отправку, поэтому у партнера нет возможности узнать, когда достигнут конец сообщения.TCP является потоковым транспортом, поэтому вам нужно поместить сообщения в протокол данных.Передайте длину сообщения перед отправкой самого сообщения.Или отправьте уникальный терминатор после сообщения.Затем узел может прочитать длину перед прочтением сообщения или прочитать, пока не будет достигнут терминатор.
Оба send()
и read()
возвращают, сколько байтов было фактически отправлено / получено, что может быть (и частоis) меньше байтов, чем запрошено.Вам нужно вызывать их в цикле, чтобы убедиться, что вы отправляете / получаете все, что ожидаете.
Кроме того, read()
не возвращает строку с нулевым символом в конце, но использование printf()
ожидает,Проверьте valread
на наличие ошибок, и только если read()
был успешным, передайте valread
в printf()
в качестве входного параметра, чтобы он знал, сколько данных на самом деле находится в buffer
:
printf("message from client : %.*s\n", valread, buffer);
printf("response from buffer : %.*s\n", valread, buffer);