2013-05-26 3 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); 
} 

그리고 무슨 일이 일어나는가는 syscall 연결 thread: connect: Network is unreachable을 연결하는 것입니다.

if (fd[1].revents) 
    printf("Loopback socket\n"); 

이 소켓 어떤 interraction가 있는지 여부를 확인하기 위해,하지만 아무것도를 출력하지 : 서버의 메인 루프에서

나는이 있습니다.

내부 소켓을 설정하는 방법을 잘 모르겠습니다. 튜토리얼을 읽었을 때 환영받을만한 링크가 있습니다.

뭔가 간단 할 수도 있지만 소켓 프로그래밍을 처음 접했을 때 찾을 수 없었습니다.


편집 :
제안 ALK로 (INADDR_LOOPBACK를) htonl 여전히 연결이 실패하는 IN_LOOPBACKNET을 변경 한 후하지만 새 메시지, connection refused와.
그러나 여전히, fds [2]로부터의 반향은 없습니다.

+0

서버가'bind()'를 호출하지 못했습니까? – alk

+0

@alk : 아니요, 거기에 오류가 없습니다 :/내가 게시 한 코드의 두 번째 블록에 잘못된 것이 있어야합니다. 서버는 클라이언트의 "외부"통신을 잘 처리합니다. 그러나 연결이 내부 소켓에서 거부되었습니다. – Chris

답변

1

오류 메시지 (Network is unreachable)에서 주소 지정과 관련된 문제가 있다고 결론을 내릴 수 있습니다. 이 로컬 루프백 네트워크의로

그래서 당신은,

IN_LOOPBACKNET 

가장 가능성이 당신이 원하는 것을하지 127

INADDR_LOOPBACK 

전 결의를로 변경하려면 있습니다.

후자는 루프백 주소 127.0.0.1의 정수 표현 인 0x7f000001으로 해결되므로 더 적합합니다.


은 또한 당신은 IP 주소를 할당 할 때 클라이언트가 연결된다 바이트 순서를 네트워크로 전환 ( htonl()를) 누락되었습니다.

+0

나는 무슨 일이 있었는지 알아 내려고 노력 중이었고 gethostbyname을 사용하여 클라이언트 응용 프로그램에서 "localhost"라는 인수로 사용하고 있기 때문에 gethostbyname을 사용하고 나면 연결이 거부되었습니다. 지금, 나는 당신이 나를 게시하고 여전히 서버의 메인 루프에서 어떤 인쇄도없이'connection refused'를 얻는 코드를 업데이트했다. – Chris

+0

@Chris : 접속을 기다리는 서버 소스의 일부를 보여주지는 못했지만, 그렇게하기 위해서는'accept()'호출이 필요하다는 것을 알고 있습니까? 그렇습니다. 'Connection refused'는 클라이언트에게 당신이 접속하려고 시도하고있는 주소 : 포트에서 accept()를 기다리는 사람이 없다는 것을 알려줍니다. – alk

+0

예 알크, 나는 받아 들여야한다는 것을 안다. 문제는 서버에서 로컬 호스트의 주소입니다. 알면 IN_LOOPBACKNET이고 INADDR_LOOPBACK이어야합니다. 도와 줘서 고마워! 또한 네트워크를 통해 전송되는 모든 숫자를 htonl/s로 변환해야합니까? – Chris