소켓 프로그램 컴파일 문제 입니다.(리눅스에서 잘됨.. 솔라리

qprk의 이미지

리눅스에서 gcc agent.c
하면 아무 불평없이 컴파일 잘 되고 동작도 잘 합니다.

하지만 솔라리스에서 gcc agent.c
하면 아래와 같은 메시지를 뿌립니다.

Quote:

정의되지 않음 첫번째 참조된
기호 파일의
socket /var/tmp//ccZJnigl.o
gethostbyname /var/tmp//ccZJnigl.o
inet_addr /var/tmp//ccZJnigl.o
connect /var/tmp//ccZJnigl.o
ld: 치명적: 기호 참조 오류. a.out에 출력이 기록되지 않음
collect2: ld returned 1 exit status

솔라리스에서 코딩이 처음이라.. 난감하내요 :cry:

소스코드는 아래와 같습니다.

#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <errno.h>
#include <signal.h>

#define DEFAULT_PORT    80
#define MAX_HTML_BUFF   1000000 /* html file을 저장할 공간 */
#define INADDR_NONE	-1

struct sockaddr_in serverAddress;
struct hostent hostInfo;


int startRobot(char *, char *, char *);
int HTTPConnect(char *);
void Request(int ,char *);
long Response(int , char *);
int CheckStatus(char *);


void time_out(int );

int HTTPConnectSockFD;

long fileSize;


void time_out(int sig)
{
  close(HTTPConnectSockFD);
}

void SigExit(int sig)
{
  printf("===== ERROR SIG_TYPE: %d =====\n",sig);
  printf("===== ERROR NO: %d, %s =====\n",errno, strerror(errno));
  signal(SIGINT,SIG_IGN);
  kill(0,SIGINT);
  printf("\a !!! 오류 : \033[>7m프로그램이 비정상적으로 종료되었습니다 \033[0m\n");
  exit(-1);
}

void Signal(void)
{
  signal(SIGQUIT,SigExit);
  signal(SIGINT,SigExit); 
  signal(SIGTERM,SigExit);
  signal(SIGHUP,SigExit); 
  signal(SIGSEGV,SigExit);
  signal(SIGBUS,SigExit); 
  signal(SIGKILL,SigExit);

  signal(SIGALRM, time_out);

}//Signal()

/***************************************************************
 * main
 * 각종 기본 환경 설정
 ***************************************************************/
int main()
{
  char htmlBuff[MAX_HTML_BUFF];
  
  Signal();

  printf("===============================================\n");
  if((startRobot("www.***.co.kr", "*****.html", htmlBuff)) == -1) {
    printf("[<31mstartRobot() error!![<0m\n");
    //	  continue;
  }

  close(HTTPConnectSockFD);
  return 0;
}

/***************************************************************
 * url을 할당받아 로봇을 가동
 ***************************************************************/
int startRobot(char *host, char *uri, char *htmlBuff)
{
  char jobUrl[512];
  int sockfd;
  FILE *fp;
  char *noHeader;
  


  sockfd = HTTPConnect(host);
  if (sockfd == -1)
    return -1;
  Request(sockfd,uri);

  /* 서버로 부터의 응답 메세지가 없을 경우 */
  if((fileSize=Response(sockfd, htmlBuff)) <=0 ) {
    printf("No Response From\n");
    return -1;
  }

  //  resetBuff=fileSize;
  sprintf(jobUrl, "%s%s",host,uri);
 //  printf("\njobUrl -> %s\n\n",jobUrl);


  noHeader = strstr(htmlBuff, "\r\n\r\n");




  fp = fopen("out.html", "w");
  fprintf(fp, "%s", noHeader + 4);







  return 1;
}


/***************************************************************
 * host에 접속
 ***************************************************************/
int HTTPConnect(char *hostname)
{
  int status;
  unsigned long IPAddr;
  struct hostent *hostp;
  //  char **addrs;
  char portBuff[512];
  int isPort, i;

  isPort = 0;
  memset(portBuff, 0, 512);
  strncpy(portBuff, hostname, 512);
  //  signal(SIGALRM, time_out);
  bzero((char *)&serverAddress, sizeof(serverAddress));
  serverAddress.sin_family = AF_INET;

  //  prot 추출하기
  if(strchr(portBuff, ':') != NULL) {
    for(i=0; portBuff[i] != ':' ; i++) ;
    portBuff[i]= '\0';
    //    printf("  여긴가???,,,%d,,,%c,,,%s\n",i , portBuff[i], &portBuff[i+1]);
    isPort = atoi(&portBuff[i+1]);
  }  

  if(isPort)			/* 80port 말고 다른거 사용할 경우 */
    serverAddress.sin_port = htons(isPort);
  else
    serverAddress.sin_port = htons(DEFAULT_PORT);

  //  printf("사용 포트는 ???  %d\n",isPort);
  
  /* IP 주소인지 도메인 이름인지 체크한다. */
  if((IPAddr = inet_addr(portBuff)) != INADDR_NONE){
    bcopy((char *)&IPAddr,(char *)&serverAddress.sin_addr,sizeof(IPAddr));
    hostInfo.h_name = NULL;
  }
  else
    {
      if((hostp = gethostbyname(portBuff)) == NULL){
	printf("[<31m!!!!TCP Error[<0m : hostname error %s\n",portBuff);
	return(-1);
      }
      //      addrs = hostp->h_addr_list;
      //      printf("host ip = %s\n", inet_ntoa(*(struct in_addr *)*addrs));
      hostInfo = *hostp;
      bcopy(hostp->h_addr, (char *)&serverAddress.sin_addr, hostp->h_length);
    }  

  /* 실제로 소켓을 열어서 서버와 연결 */
  HTTPConnectSockFD = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  if(HTTPConnectSockFD < 0){
    printf("[<31m[x][0m Socket open error!\n");
    return -1;
  }
  
  alarm(3);
  status = connect(HTTPConnectSockFD, (struct sockaddr *)&serverAddress, sizeof(serverAddress));
  if(status < 0) {
    //    printf("[<31m호스트에 연결이 되지 않습니다.[0m\n");
    alarm(0);
    return -1;
  }//  if(status < 0) {
  //  printf("[<32m[o][0m 성공적으로 연결되었습니다.\n");
  return HTTPConnectSockFD;
}



/***************************************************************
 * 접속된 host에 html 문서를 요청
 ***************************************************************/
void Request(int reqsockfd, char *refer)
{
  char message[512];

  sprintf(message,"GET %s HTTP/1.0\r\n\n",refer);
  //  sprintf(message,"GET %s HTTP/1.0\n\n",refer);
  //  printf("....%s....\n",message);

  /* 실제로 소켓을 통해서 메세지를 보낸다. */
  write(reqsockfd,message,sizeof(message));
}



/***************************************************************
 * 받아온 문서를 분석하여 정상적으로 처리가 되었는지 확인
 ***************************************************************/
long Response(int ressockfd, char *htmlBuff )
{
  int cnt=0, readcnt=0;
  char ch, headers[512];
  long i;
  

  do{
    if((readcnt = read(ressockfd, &ch,1)) == 1){
      headers[cnt++] = ch;
      //      printf("%c",ch);
    }else{
      printf("[<31m[x][<0m Socket read error\n");
      //    close(HTTPConnectSockFD);
      return (-1);
    }
  }while(ch != '\n');

  if(!CheckStatus(headers)){
    printf("[<31m[x][<0m 서버의 상태 코드가 2xx 게열이 아닙니다.\n");
    //    close(HTTPConnectSockFD);
    return (-1);
  }
  
  //  if((fp = fopen(K_BOT,"w")) == NULL){
  //    printf("[%s] 파일을 열 수 없습니다.\n",K_BOT);
  //    return (-1);
  //  }

  for(i=0; (readcnt = read(ressockfd,&ch,1)); i++)  {
    if(readcnt == 1)
      *(htmlBuff+i)=ch;
      //      fputc( ch, fp);
    else{
      printf("[<31m[x][<0m Not reading\n"); 
      //      close(HTTPConnectSockFD);
      return i;
    }
    if (i >= MAX_HTML_BUFF -1) {
      printf("htmlBuff is Full!!\n"); 
      return i;
    }
  }

  //  fclose(fp);
  //  printf("[<32m[o][0m 무사히 저장되었습니다.\n");
  //  close(HTTPConnectSockFD);
  return i;
}

/***************************************************************
 * http 해더가 정상인지 확인
 ***************************************************************/
int CheckStatus(char *count)
{   
  int i,k=0;
  int j=0,l=0;
  char res[200];
  
  for(i=0;i<strlen(count);i++){
    if(*(count + i) == ' '){
      l++;
      for(k=1;;k++){
	res[j++] = *(count+i+k);
	if(*(count+i+k) == ' ')
	  break;
      }
      res[j-1]='\0';
    }
    if(l == 1)
      break;
  }
  
  if(atoi(res)>=300)
    return 0;
  else return 1;
}



godyang의 이미지

안녕하세요?

링크 문제로 보입니다.

socket관련 함수를 쓰기 위해 socket 라이브러리를 링크하시고,
gethostbyname함수를 쓰기 위해 nsl라이브러리를 링크하시면 될 겁니다.

gcc test.c -lnsl -lsocket

참고삼아... 제쪽에서 테스트해보니 FILE *fp때문에 컴파일되지 않았습니다.
stdio.h를 include해야할 것 같습니다.

위와 같은 내용은 man 페이지를 참고하면 웬만한 정보는 다 있으므로
자주 써먹으시면 도움될 겁니다.

그럼...

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.