2013-12-16 3 views
5

나는 프로그램을 클라이언트/서버 스타일로 작성하고 있습니다. 이제 서버 측을 개발 중이며 소켓을 엽니 다.누가 C 소켓으로 연결합니까?

하지만 누가 내 소켓에 연결되어 있는지 알아야합니다. 어떤 IP가 연결되어 있습니까? 왜냐하면 나는 서버에 접속하는 로그를 넣어야하기 때문이다.

그래서 제 질문은 어떻게 C에서이 작업을 수행 할 수 있습니까? Linux 사용.

getsockopt()을 사용해 보려하지만 작동하지 않습니다. 그리고 저는 네트워크 프로그래밍에 대해 새로운 사람입니다.

어떻게하면 알 수 있습니까? 도움을

int init_socket() { 
    /** Declara um socket */ 
    Socket sock; 

    /** Inicia o socket */ 
    sock.socket = socket(AF_INET, SOCK_STREAM, 0); 

    /** Seta zeros no sockaddr */ 
    memset(&sock.server, 0, sizeof (sock.server)); 

    /** E tambem no buffer */ 
    memset(sock.buff, 0, sizeof (sock.buff)); 

    /** Seta os valores do sockaddr */ 
    sock.server.sin_family = AF_INET; 
    sock.server.sin_addr.s_addr = htonl(INADDR_ANY); 
    //sock.server.sin_port = htons(get_config_int(&conf, "monitor_port")); 
    sock.server.sin_port = htons(2200); 

    /** Chama o bind */ 
    bind(sock.socket, (struct sockaddr*) &sock.server, sizeof (sock.server)); 

    /* 
    * É um socket blocante, então espera encher o buffer 
    * Faz o listen 
    */ 
    if (listen(sock.socket, 2) == -1) { 
     /** Deu falha na preparação para o accept, insere nos logs */ 
     insert_log(FATAL, LOG_KERNEL, "Não foi possível iniciar o socket - event.c"); 

     /** Retorna falha */ 
     return INIT_SOCKET_FAILED; 
    } 

    /** Se chegar aqui, faz o accept, dentro de um loop infinito */ 
    connect: 
    while ((sock.conn = accept(sock.socket, (struct sockaddr*) NULL, NULL))) { 
     printf("Recebi uma conexão, começando comunicação...\n"); 
     /** Agora conn é um file descriptor, podemos ler e gravar nele */ 
     while (1) { 
      if (read(sock.conn, sock.buff, sizeof (sock.buff)) == 0) { 
       close(sock.conn); 
       printf("Pronto para outra conexão...\n"); 
       goto connect; 
      } 
      printf("Eu Li isso do Buffer: %s", sock.buff); 

      /** Limpa o buffer */ 
      memset(sock.buff, 0, sizeof (sock.buff)); 
      sleep(1); 
     } 
    } 

    return INIT_SOCKET_SUCCESS; 
} 

감사 :

여기 내 소켓의 코드입니다!

struct sockaddr_storage remoteAddr; 
socklen_t remoteAddrLen = sizeof(remoteAddr); 

sock.conn = accept(sock.socket, (struct sockaddr *)&remoteAddr, &remoteAddrLen); 

당신은 다음 getnameinfo에서 (로 문자열로 원격 주소를 변환 할 수 있습니다)이 작동 : 당신이 인수로 struct sockaddr의 주소 를 전달하는 경우

+3

'getpeername()'을 사용하십시오. –

+0

@ n.m .: 답변 대신 의견을 말하십시오. – wilx

답변

3

accept() 전화는 당신에게 원격 주소를 제공합니다 IPv4와 IPv6 모두 :

char host[NI_MAXHOST]; 
getnameinfo((struct sockaddr *)&remoteAddr, remoteAddrLen, host, sizeof(host), NULL, 0, NI_NUMERICHOST); 
1

귀하의 질문에 대한 답이 맞는지 잘 모르겠습니다. 그런 다음 cli_addr를 사용하여 IP 주소를 표시하는 inet_ntoa()를 사용

struct sockaddr_in cli_addr; 

그런 다음 서버 코드

newsockfd = accept(sockfd,(struct sockaddr *) &cli_addr, &clilen); 

의 무한 루프에있을 수 있습니다 사용할 수 있습니다.

0

D.J. Bernstein의 tcpserver (http://cr.yp.to/ucspi-tcp/tcpserver.html 참조). 기본적으로 tcpserver에서 C 프로그램을 실행하면 tcpserver는 소켓 설정, 사용중인 포트에서 들어오는 연결 나열 등 모든 작업을 처리합니다. 들어오는 연결이 지정한 포트에 도착하면, tcpserver는 프로그램의 인스턴스를 생성하고 클라이언트로부터 들어오는 정보를 프로그램의 STDIN으로 파이프하고 프로그램의 STDOUT에서 나가는 정보를 다시 클라이언트로 파이프합니다. 이렇게하면 프로그램의 핵심 로직 (stdout/stdin에 읽기/쓰기 만 가능)에 집중할 수 있고 tcpserver는 소켓까지 무거운 것을 모두 처리 할 수 ​​있습니다. 클라이언트의 IP 주소를 얻으려면 $ TCPREMOTEIP 환경 변수.

관련 문제