2012-04-18 3 views
0

서버에 연결중인 클라이언트를 쓰고 있습니다. 나는 TCP 소켓의 memcpy() 라인 124에 Segmentation Fault를 가지고있다. UDP 연결을 사용하여 네트워크에서 서버의 IP 주소를 얻고 싶으면 IP를 얻은 다음 TCP 연결을 통해 연결하려고합니다. TCP 연결 자체의 코드는 새로운 파일에서 컴파일 할 수 있기 때문에 작동합니다. 나는 문제가 어디 있는지 이해하지 못한다.memcpy tcp 소켓의 세그먼트 오류

#include <stdio.h>  
#include <sys/types.h> 
#include <ifaddrs.h> 
#include <netinet/in.h> 
#include <string.h> 
#include <arpa/inet.h> 
#include <string.h> 
#include <memory.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <sys/types.h> 
#include <netdb.h> 
#include "main.h" 

int developer=1; 
struct myHelloMsg { 
    char myIp[25]; 
    char myID[25]; 
}; 
int FindMyIp(char myIpAddr[], char myMask[], char myBroad[]); 
int RecvBroadTime(int sockfd, struct sockaddr_in server_addr); 
void CheckID(char myUserID[]); 

int main() { 
    char myIpAddr[25], myMask[25], myBroad[25], myUserID[25]=""; 
    char otherUserIp[25], otherUserID[25]; 
    struct myHelloMsg myMsg, rxMsg; 
    CheckID(myUserID); 
    int checkConnection; 
    disconnected: ; 
    checkConnection=0; 
    if (developer==1) printf("\nSearching for a network..\n"); 
    while (checkConnection == 0) { 
     checkConnection = FindMyIp(myIpAddr, myMask, myBroad); 
     if (checkConnection==0) { 
      if (developer==1) printf("--Disconnected..\n"); 
      sleep(5); 
     } 
    } 
    if (developer==1) printf("\n--Connected..\nIP Address\t: %s\n", myIpAddr); 
    if (developer==1) printf("Subnet Mask\t: %s\n", myMask); 
    if (developer==1) printf("Broadcast IP\t: %s\n", myBroad); 

    int i=0; 
    for (i=0;i<25;i++) { 
     myMsg.myIp[i]=myIpAddr[i]; 
     myMsg.myID[i]=myUserID[i]; 
    } 
    struct hostent *hptr = gethostbyname(myBroad); 
    if (hptr == NULL) { 
     if (developer==1) printf("Error while transmitting broadcast message..\n"); 
     return 0; 
    } 
    // create socket for initial UDP communication 
    int sockfd = socket(AF_INET, SOCK_DGRAM, 0); 
    struct sockaddr_in server_addr; 
    bzero(&server_addr, sizeof(struct in_addr)); 
    server_addr.sin_family = AF_INET; 
    server_addr.sin_port = htons(5051); 
    server_addr.sin_addr.s_addr = htonl(INADDR_BROADCAST); 
    memcpy(&server_addr.sin_addr, hptr->h_addr_list[0], sizeof(struct in_addr)); 
    int opt = 1; 
    setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &opt, sizeof(int)); 
    int error=0; 
    if (developer==1) printf("--Contacting other users in the network..\n"); 
    sendto(sockfd, &myMsg, sizeof(myMsg), 0, (struct sockaddr *) &server_addr, sizeof(struct sockaddr_in)); 
    int foundSomeone=0; 
    //try to connect with others for 5 times - because of UDP unreliable connection 
    int countTries=0, received=0, lastTry=0; 
    while (countTries<5) { 
     foundSomeone = RecvBroadTime(sockfd, server_addr); 
     if (foundSomeone == 1) { 
      if (developer==1) printf("An answer has been received..\n"); 
      socklen_t ssize = sizeof(struct sockaddr_in); 
      recvfrom(sockfd, &rxMsg, sizeof(rxMsg), 0, (struct sockaddr *) &server_addr, &ssize); 
      received=1; 
      countTries=5; 
     } 
     else if (foundSomeone == 0) { 
      if (developer==1) printf("Timeout(%d try)..\n", countTries+1); 
      sendto(sockfd, &myMsg, sizeof(myMsg), 0, (struct sockaddr *) &server_addr, sizeof(struct sockaddr_in)); 
      if (countTries==4) { 
       lastTry=1; 
      } 
     } 
     else { 
      if (developer==1) printf("--Error..\n"); 
     } 
     countTries++; 
    } 
    if ((lastTry==1)&&(countTries==5)) { 
     foundSomeone = RecvBroadTime(sockfd, server_addr); 
     if (foundSomeone == 1) { 
      if (developer==1) printf("An answer has been received..\n"); 
      socklen_t ssize = sizeof(struct sockaddr_in); 
      recvfrom(sockfd, &rxMsg, sizeof(rxMsg), 0, (struct sockaddr *) &server_addr, &ssize); 
      received=1; 
     } 
     else if (foundSomeone == 0) { 
      if (developer==1) printf("--No one is connected to the current network..\n"); 
     } 
     else { 
      if (developer==1) printf("There has been an error while trying to contact other users..\n"); 
     } 
    } 
    close(sockfd); 
    // someone else is connected to the network 
    // i am gonna behave as a client in during the synchronization step 
    if (received==1) { 
     if (developer==1) printf("Contact made with user %s (%s).\n", myMsg.myID, myMsg.myIp); 
     // check if the user belong to friends i am sharing content with 
     i=0; 
     for (i=0;i<25;i++) { 
      otherUserIp[i]=rxMsg.myIp[i]; 
      otherUserID[i]=rxMsg.myID[i]; 
     } 
     int socktcp = socket(AF_INET, SOCK_STREAM, 0); 
     struct hostent *hptr_tcp = gethostbyname(otherUserIp); 
     struct sockaddr_in server_addr_tcp; 
     bzero(&server_addr_tcp, sizeof(struct sockaddr_in)); 
     server_addr_tcp.sin_family = AF_INET; 
     server_addr_tcp.sin_port = htons(5054); 
     printf("a\n"); 
     memcpy(&server_addr_tcp.sin_addr, hptr_tcp->h_addr_list[0], sizeof(struct in_addr)); 
     printf("a\n"); 
     if (connect(socktcp, (struct sockaddr *) &server_addr_tcp, sizeof(struct sockaddr_in))<0) { 
      printf("-Error..\n"); 
     } else { 
      printf("Connection with %s established.. Ready for synchronization step..\n", otherUserID); 
     } 
    } 

    return 0; 
} 


int RecvBroadTime(int sockfd, struct sockaddr_in server_addr) { 
    fd_set socks; 
    struct timeval t; 
    t.tv_sec = 1; 
    t.tv_usec = 0; 
    FD_ZERO(&socks); 
    FD_SET(sockfd, &socks); 
    return select(sockfd+1, &socks, NULL, NULL, &t); 
} 

int FindMyIp(char myIpAddr[], char myMask[], char myBroad[]) { 
    struct ifaddrs * ifAddrStruct=NULL; 
    struct ifaddrs * ifa=NULL; 
    void * tmpAddrPtr=NULL; 
    getifaddrs(&ifAddrStruct); 
    int i=0, connected=0; 
    ifa = ifAddrStruct; 
    while (i!=1) { 
     if (((ifa ->ifa_addr->sa_family==AF_INET)&&(ifa->ifa_name[0]=='e')&&(ifa->ifa_name[1]=='n')&&(ifa->ifa_name[2]=='1'))||((ifa ->ifa_addr->sa_family==AF_INET)&&(ifa->ifa_name[0]=='e')&&(ifa->ifa_name[1]=='t')&&(ifa->ifa_name[2]=='h')&&(ifa->ifa_name[3]=='0'))) { 
      i=1; 
      connected=1; 
     } else { 
      if (ifa->ifa_next == NULL) return connected; 
      ifa = ifa->ifa_next; 
     } 
    } 
    tmpAddrPtr=&((struct sockaddr_in *)ifa->ifa_addr)->sin_addr; 
    inet_ntop(AF_INET, tmpAddrPtr, myIpAddr, INET_ADDRSTRLEN); 
    tmpAddrPtr=&((struct sockaddr_in *)ifa->ifa_netmask)->sin_addr; 
    inet_ntop(AF_INET, tmpAddrPtr, myMask, INET_ADDRSTRLEN); 
    tmpAddrPtr=&((struct sockaddr_in *)ifa->ifa_broadaddr)->sin_addr; 
    inet_ntop(AF_INET, tmpAddrPtr, myBroad, INET_ADDRSTRLEN); 
    return connected; 
} 

void CheckID(char myUserID[]) { 
    FILE *fp; 
    if((fp=fopen("userData.txt", "r+"))==NULL) { 
     printf("Error while opening the file..\n"); 
    } 
    else { 
     fscanf(fp, "%25s", myUserID); 
     if (strlen(myUserID)==0) { 
      printf("First time you open this app..\nInsert your User ID: "); 
      scanf("%s", myUserID); 
      fprintf(fp, "%-25s", myUserID); 
     } 
     else { 
      printf("Welcome back %s..\n", myUserID); 
     } 
     fclose(fp); 
    } 
} 
+0

게시 한 코드의 124 행은 어디에 있습니까? 말할 수 없습니다. –

+0

이 하나 :) 죄송합니다 memcpy (& server_addr_tcp.sin_addr, hptr_tcp-> h_addr_list [0], sizeof (struct in_addr)); – phcaze

+3

다음을 수행하십시오. 오류를 표시하는 데 필요한 최소 수준으로 코드를 줄이십시오. 오류가 사라질 때까지 한 번에 코드의 일부를 제거한 다음 편집 한 마지막 항목을 다시 넣으십시오. 코드를 줄이면이 ​​방법으로 범위를 좁힐 수 있기 때문에 이미 오류를 찾는 데 도움이됩니다. 가능한 한 많이 줄 였지만 여전히 오류를 찾지 못한 경우 축소 된 코드, 예상되는 출력/동작 및 현재 얻고있는 출력/동작을 게시하십시오. 자세한 내용은 http://homepage1.nifty.com/algafield/sscce.html을 참조하십시오. – LiKao

답변

1

나는 gethostbyname()을 사용하여 브로드 캐스트 주소를 확인할 수 없다고 말하고 싶습니다. 또한


: gethostbyname()가 사용되지 않습니다, 대신 getnameinfo()를 사용합니다.

+0

모든 답장을 보내 주셔서 감사합니다. 문제는 클라이언트의 사용자 이름을 확인하기위한 txt 파일을 여는 기능입니다. 나는 (fp = fopen ("userData.txt", "rb +")) == NULL)에서 if ((fp = fopen ("userData.txt", "r +")) == NULL) . 실제로 나는 왜 그것이 코드의 다른 부분에있는 그 memcpy에 세분화 결함을 주는지 이해할 수 없다. – phcaze