2013-05-26 2 views
0

Я пытаюсь создать локальное соединение между потоками одного и того же процесса, используя гнездо семейства 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"); 

, чтобы проверить, есть ли interraction с этим сокетом, но это никогда не печатает ничего.

Я не уверен, как настроить внутренний сокет, если есть учебник, который я мог бы прочитать, ссылка была бы более чем приветствуется!

Это может быть что-то простое, но поскольку я новичок в программировании сокетов, я не могу его найти.


Edit:
После изменения IN_LOOPBACKNET к Htonl (INADDR_LOOPBACK) в качестве алк предлагаемого подключить все еще не, но с новым сообщением, connection refused.
Но все же, нет никаких отступлений от fds [2].

+0

Не вызвал ли запрос сервера 'bind()' сообщение об ошибке? – alk

+0

@alk: Нет, нет ошибок:/Должно быть что-то не так со вторым блоком кода, который я опубликовал. Сервер обрабатывает только тонкую «внешнюю» связь клиента. Но получение соединения отказалось от внутреннего сокета. – Chris

ответ

1

Из сообщения об ошибке (Network is unreachable) вы могли бы заключить, что есть что-то подозрительное с адресацией.

Таким образом, вы могли бы изменить

IN_LOOPBACKNET 

быть

INADDR_LOOPBACK 

Бывших ПОСТАНОВЛЯЕТ 127, который, скорее всего, это не то, что вы хотите, поскольку это локальная сеть шлейфа.

Последний подходит лучше, поскольку он разрешает 0x7f000001, что является целым представлением обратного адреса 127.0.0.1.


Также отсутствует преобразование в сетевой порядок байтов (htonl()) при назначении IP-адрес клиента должен подключаться.

+0

Я пытался выяснить, что произошло, и я использовал gethostbyname, поскольку я использую его с моим клиентским приложением, предоставляя его как аргумент «localhost», и он работал, давая мне «соединение отказано». Теперь я обновил код с тем, что вы отправили мне и все еще получал «отказ от соединения» без печати из основного цикла сервера. – Chris

+0

@Chris: вы не показываете часть источников сервера, которая действительно ждет подключения, но вы знаете, что для этого требуется вызов 'accept()', не так ли? 'Соединение отклонено 'просто сообщает клиенту, что нет ожидающего' accept() 'соединения по адресу: порт, который вы пытаетесь подключить. – alk

+0

Да, я знаю, что мы должны принять. Проблема заключалась в адресе localhost на сервере. Если вы заметили, это IN_LOOPBACKNET, в то время как это должно быть INADDR_LOOPBACK. Спасибо за помощь! Кроме того, не могли бы вы ответить на меня, если ВСЕ числа, которые отправляются по сети, будут преобразованы с помощью htonl/s? – Chris

 Смежные вопросы

  • Нет связанных вопросов^_^