Попытка установить внутреннее соединение с сокетами между потоками и соединиться не удается
Я пытаюсь создать локальное соединение между потоками одного и того же процесса, используя сокет семейства AF_INET.
Сервер должен обрабатывать клиентов и обслуживать их запросы через мультиплексирование с потоками.
Таким образом, в главном потоке сервера у меня есть это для внешнего соединения:(проверка на наличие ошибок опущена для поддержания разумной длины сообщения)
struct sockaddr_in server_addr;
struct sockaddr *serverptr=(struct sockaddr *)&server_addr;
listening_sock = socket(AF_INET, SOCK_STREAM, 0);
fds[0].fd = listening_sock;
fds[0].events = POLLIN;
// Setting listening socket
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
int one = 1;
setsockopt(listening_sock, SOL_SOCKET, SO_REUSEADDR, (void *)&one, sizeof(one));
setsockopt(listening_sock, IPPROTO_TCP, TCP_NODELAY, (void *)&one, sizeof(one));
bind(listening_sock, serverptr, sizeof(server_addr));
listen(listening_sock, 5);
и затем с помощью опроса я успешно опрашиваю сокет прослушивания (общение с клиентом).
Теперь я хочу создать внутренний сокет через TCP для связи между основным потоком и новым потоком, который я создам.
Я добавил это:
struct sockaddr_in loopback_addr;
struct sockaddr *loopbackptr=(struct sockaddr *)&loopback_addr;
loopback_sock = socket(AF_INET, SOCK_STREAM, 0); //checking for errors is omitted
fds[1].fd = loopback_sock;
fds[1].events = POLLIN;
// Setting loopback socket
loopback_addr.sin_addr.s_addr = htonl(IN_LOOPBACKNET);
loopback_addr.sin_family = AF_INET;
loopback_addr.sin_port = htons(18000);
int one = 1;
setsockopt(loopback_sock, SOL_SOCKET, SO_REUSEADDR, (void *)&one, sizeof(one));
setsockopt(loopback_sock, IPPROTO_TCP, TCP_NODELAY, (void *)&one, sizeof(one));
bind(loopback_sock, loopback_ptr, sizeof(loopback_addr));
listen(loopback_sock, 5);
А также увеличил счетчик nfds до 2.
Теперь поток запускается перед циклом опроса и пытается связаться с этим кодом:
struct sockaddr_in server;
struct sockaddr *serverptr = (struct sockaddr*)&server;
int sock;
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
perror("thread: socket");
pthread_exit((void*)-1);
}
int port = 18000;
server.sin_family = AF_INET;
server.sin_addr.s_addr = IN_LOOPBACKNET;
server.sin_port = htons(port);
if (connect(sock, serverptr, sizeof (server)) < 0)
{
perror("thread: connect");
pthread_exit((void*)-1);
}
И что происходит, то, что Connect SysCall возвращает thread: connect: Network is unreachable
,
В основном цикле сервера у меня есть это:
if (fd[1].revents)
printf("Loopback socket\n");
чтобы проверить, есть ли какое-либо взаимодействие с этим сокетом, но это никогда ничего не печатает.
Я не уверен, как настроить внутренний сокет, если есть учебник, который я мог бы прочитать, ссылка будет более чем приветствоваться!
Это может быть что-то простое, но, поскольку я новичок в программировании сокетов, я не могу его найти.
Редактировать:
После изменения значения IN_LOOPBACKNET на htonl(INADDR_LOOPBACK), как было предложено alk, установить соединение по-прежнему не удается, но с новым сообщением, connection refused
,
Но, тем не менее, от фдс нет никаких отторжений [2].
1 ответ
Из сообщения об ошибке (Network is unreachable
) вы могли бы заключить, что с адресацией есть что-то подозрительное.
Так что вы можете изменить
IN_LOOPBACKNET
быть
INADDR_LOOPBACK
Бывший решает 127
что, скорее всего, не то, что вы хотите, так как это локальная петлевая сеть.
Последний подходит лучше, так как он решает 0x7f000001
, которое является целочисленным представлением адреса обратной связи 127.0.0.1
,
Также вам не хватает преобразования в сетевой порядок байтов (htonl()
) при назначении ip-адреса клиент должен подключиться.