免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 4911 | 回复: 10
打印 上一主题 下一主题

程序编译时连接出错,请指教! [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-12-02 21:38 |只看该作者 |倒序浏览
今天编译一个网络服务程序,在运行gcc -o server.o server.c 命令后,发现汇编没有问题,但连接出错。请高手指教。
下面把源代码和出错信息都给上。
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <netdb.h>
#define TCP_PROTO  "tcp"
int proxy_port;  /* port to listen for proxy connections on */
struct sockaddr_in hostaddr;  /* host addr assembled from gethostbyname() */
extern int errno;  /* defined by libc.a */
extern char *sys_myerrlist[];
void parse_args (int argc, char **argv);
void daemonize (int servfd);
void do_proxy (int usersockfd);
void reap_status (void);
void errorout (char *msg);
/*This is my modification.
I'll tell you why we must do this later*/
typedef void Signal(int);
/****************************************************************
function: ...main
description: . Main level driver. After daemonizing the process, a socket is opened to listen for ........connections on the proxy port, connections are accepted and children are spawned to ........handle each new connection.
arguments: .. argc,argv you know what those are.
return value: .none.
calls: .... parse_args, do_proxy.
globals: ... reads proxy_port.
****************************************************************/
main (argc,argv)
int argc;
char **argv;
{
int clilen;
int childpid;
int sockfd, newsockfd;
struct sockaddr_in servaddr, cliaddr;
parse_args(argc,argv);
/* prepare an address struct to listen for connections */
bzero((char *) &servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = proxy_port;
/* get a socket... */
if ((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0) {
/* get a socket... */
if ((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0) {
fputs("failed to create server socket\r\n",stderr);
exit(1);
}
/* ...and bind our address and port to it */
if(bind(sockfd,(struct sockaddr_in *) &servaddr,sizeof(servaddr)) < 0) {
fputs("faild to bind server socket to specified port\r\n",stderr);
exit(1);
}
/* get ready to accept with at most 5 clients waiting to connect */
listen(sockfd,5);
/* turn ourselves into a daemon */
daemonize(sockfd);
/* fall into a loop to accept new connections and spawn children */
while (1) {
/* accept the next connection */
clilen = sizeof(cliaddr);
newsockfd = accept(sockfd, (struct sockaddr_in *) &cliaddr, &clilen);
if (newsockfd < 0 && errno == EINTR)
continue;
/* a signal might interrupt our accept() call */
else if (newsockfd < 0)
/* something quite amiss -- kill the server */
errorout("failed to accept connection");
/* fork a child to handle this connection */
if ((childpid = fork()) == 0) {
close(sockfd);
do_proxy(newsockfd);
exit(0);
}
/* if fork() failed, the connection is silently dropped -- oops! */
lose(newsockfd);
}
}


出错信息如下:
[root@localhost server]#gcc   -o server.o server.c
gcc   -o server.o server.c
server.c: In function `main':
server.c:53: warning: passing arg 2 of `bind' from incompatible pointer type
server.c:65: warning: passing arg 2 of `accept' from incompatible pointer type
/tmp/ccdgt5qk.o(.text+0x1a): In function `main':
: undefined reference to `parse_args'
/tmp/ccdgt5qk.o(.text+0xdb): In function `main':
: undefined reference to `daemonize'
/tmp/ccdgt5qk.o(.text+0x123): In function `main':
: undefined reference to `errorout'
/tmp/ccdgt5qk.o(.text+0x14d): In function `main':
: undefined reference to `do_proxy'
/tmp/ccdgt5qk.o(.text+0x165): In function `main':
: undefined reference to `lose'
collect2: ld returned 1 exit status
make: *** [server.o] Error 1

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
2 [报告]
发表于 2007-12-03 08:58 |只看该作者
把需要的库加上。BTW,既然你知道是链接错误,没有理由不清楚怎么排除。。。

论坛徽章:
0
3 [报告]
发表于 2007-12-03 20:38 |只看该作者
这是一个简单网络服务器例程。
真的不知道该怎么排除错误,能不能告诉我是什么库。具体一点!!!
谢谢先!

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
4 [报告]
发表于 2007-12-04 09:15 |只看该作者

回复 #3 hantor 的帖子

不清楚,查下文档,或者搜索。

论坛徽章:
0
5 [报告]
发表于 2007-12-04 17:04 |只看该作者
楼主的代码不全啊!这里应该有需要的函数:
http://fanqiang.chinaunix.net/a4/b7/20010810/1200001101.html

论坛徽章:
0
6 [报告]
发表于 2007-12-04 22:38 |只看该作者
原帖由 mymtom 于 2007-12-4 17:04 发表
楼主的代码不全啊!这里应该有需要的函数:
http://fanqiang.chinaunix.net/a4/b7/20010810/1200001101.html



http://fanqiang.chinaunix.net/a4/b7/20010810/1200001101.html里的代码编译也出同样的错误!!
奇怪了。

论坛徽章:
0
7 [报告]
发表于 2007-12-04 22:41 |只看该作者
原帖由 mymtom 于 2007-12-4 17:04 发表
楼主的代码不全啊!这里应该有需要的函数:
http://fanqiang.chinaunix.net/a4/b7/20010810/1200001101.html



mymtom,你提供的代码编译也出同样的错误。

用gcc -v server.o server.c时错误信息如下:

[root@localhost linux_3rd]#gcc -v server.o server.c
gcc: server.o: No such file or directory
Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/3.2.2/specs
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --                                              enable-shared --enable-threads=posix --disable-checking --with-system-zlib --enable-__cxa_atexit                                               --host=i386-redhat-linux
Thread model: posix
gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5)
/usr/lib/gcc-lib/i386-redhat-linux/3.2.2/cc1 -lang-c -v -D__GNUC__=3 -D__GNUC_MINOR__

论坛徽章:
0
8 [报告]
发表于 2007-12-04 22:52 |只看该作者
回楼上的同志,你用 -v 来编译?

论坛徽章:
0
9 [报告]
发表于 2007-12-05 21:35 |只看该作者
经检查,原来的帖子
http://fanqiang.chinaunix.net/a4/b7/20010810/1200001101.html
的代码有点问题,拼写错误如close写成了lose, SIGCHLD写成了SIGHLD,还有就是有中文空格,再一个是作者关于sys_errlist改成sys_myerrlist的写法是错误的,其实sys_errlist很早就在C运行库里了。改了一下编译通过了,没有运行试验过。
附件里是编译过的代码

  1. /*
  2. * 转载:
  3. * from [url]http://fanqiang.chinaunix.net/a4/b7/20010810/1200001101.html[/url]
  4. * 为了回答 ChinaUnix.net hantor 的帖子改的程序,编译通过,没有运行试验
  5. *
  6.    Proxy源代码分析--谈谈如何学习linux网络编程
  7.    本文出自:[url]http://www.china-pub.com[/url] 作者:李培源 (2001-08-10 12:00:00)

  8. /*
  9.    ◆main()函数
  10.    -----------------------------------------------------------------
  11. */
  12. #include <stdio.h>
  13. #include <ctype.h>
  14. #include <errno.h>
  15. #include <signal.h>
  16. #include <sys/types.h>
  17. #include <sys/socket.h>
  18. #include <sys/file.h>
  19. #include <sys/ioctl.h>
  20. #include <sys/wait.h>
  21. #include <sys/types.h>
  22. #include <netdb.h>

  23. #include <sys/select.h>
  24. #include <netinet/in.h>

  25. #define TCP_PROTO       "tcp"

  26. typedef void Sigfunc(int);
  27. int proxy_port;                 /* port to listen for proxy connections on */
  28. struct sockaddr_in hostaddr;    /* host addr assembled from gethostbyname() */
  29. extern int errno;               /* defined by libc.a */
  30. extern char *sys_myerrlist[];
  31. /* 原来的帖子搞错了,其实就应该是 sys_errlist */
  32. #define sys_myerrlist sys_errlist
  33. void parse_args (int argc, char **argv);
  34. void daemonize (int servfd);
  35. void do_proxy (int usersockfd);
  36. void reap_status (void);
  37. void errorout (char *msg);
  38. /*This is my modification.
  39. I'll tell you why we must do this later*/
  40. typedef void Signal(int);
  41. /****************************************************************
  42. function:    main
  43. description:    Main level driver. After daemonizing the process,
  44.                 a socket is opened to listen for connections on
  45.                 the proxy port, connections are accepted and
  46.                 children are spawned to handle each new connection.
  47. arguments:    argc,argv you know what those are.
  48. return value:  none.
  49. calls:      parse_args, do_proxy.
  50. globals:     reads proxy_port.
  51. ****************************************************************/
  52. int main(int argc, char *argv[])
  53. {
  54.         int clilen;
  55.         int childpid;
  56.         int sockfd, newsockfd;
  57.         struct sockaddr_in servaddr, cliaddr;
  58.         parse_args(argc,argv);
  59.         /* prepare an address struct to listen for connections */
  60.         bzero((char *) &servaddr, sizeof(servaddr));
  61.         servaddr.sin_family = AF_INET;
  62.         servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
  63.         servaddr.sin_port = proxy_port;
  64.         /* get a socket... */
  65.         if ((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0) {
  66.         fputs("failed to create server socket\r\n",stderr);
  67.         exit(1);
  68.         }
  69.         /* ...and bind our address and port to it */
  70.         if (bind(sockfd,(struct sockaddr *) &servaddr,sizeof(servaddr)) < 0)
  71.         {
  72.                 fputs("faild to bind server socket to specified port\r\n",stderr);
  73.                 exit(1);
  74.         }
  75.         /* get ready to accept with at most 5 clients waiting to connect */
  76.         listen(sockfd,5);
  77.         /* turn ourselves into a daemon */
  78.         daemonize(sockfd);
  79.         /* fall into a loop to accept new connections and spawn children */
  80.         while (1) {
  81.                 /* accept the next connection */
  82.                 clilen = sizeof(cliaddr);
  83.                 newsockfd = accept(sockfd, (struct sockaddr *) &cliaddr, &clilen);
  84.                 if (newsockfd < 0 && errno == EINTR)
  85.                         continue;
  86.                 /* a signal might interrupt our accept() call */
  87.                 else if (newsockfd < 0)
  88.                         /* something quite amiss -- kill the server */
  89.                         errorout("failed to accept connection");
  90.                 /* fork a child to handle this connection */
  91.                 if ((childpid = fork()) == 0)
  92.                 {
  93.                         close(sockfd);
  94.                         do_proxy(newsockfd);
  95.                         exit(0);
  96.                 }
  97.                 /* if fork() failed, the connection is silently dropped -- oops! */
  98.                 close(newsockfd);
  99.         }
  100. }
  101. /* ----------------------------------------------------------------- */
  102. /*
  103.         ◆函数parse_args()

  104.         此函数的定义是:void parse_args (int argc, char **argv);
  105. */
  106. /*-----------------------------------------------------------------*/
  107. /****************************************************************
  108. function:       parse_args
  109. description:    parse the command line args.
  110. arguments:      argc,argv you know what these are.
  111. return value:   none.
  112. calls:          none.
  113. globals:        writes proxy_port, writes hostaddr.
  114. ****************************************************************/
  115. void parse_args (argc,argv)
  116. int argc;
  117. char **argv;
  118. {
  119.     int i;
  120.     struct hostent *hostp;
  121.     struct servent *servp;
  122.     unsigned long inaddr;
  123.     struct {
  124.         char proxy_port [16];
  125.         char isolated_host [64];
  126.         char service_name [32];
  127.     } pargs;
  128.     if (argc < 4) {
  129.           printf("usage: %s <proxy-port> <host> <service-name|port-number>\r\n", argv[0]);
  130.           exit(1);
  131.     }
  132.     strcpy(pargs.proxy_port,argv[1]);
  133.     strcpy(pargs.isolated_host,argv[2]);
  134.     strcpy(pargs.service_name,argv[3]);
  135.     for (i = 0; i < strlen(pargs.proxy_port); i++)
  136.         if (!isdigit(*(pargs.proxy_port + i)))
  137.             break;
  138.     if (i == strlen(pargs.proxy_port))
  139.         proxy_port = htons(atoi(pargs.proxy_port));
  140.     else {
  141.         printf("%s: invalid proxy port\r\n",pargs.proxy_port);
  142.         exit(0);
  143.     }
  144.     bzero(&hostaddr,sizeof(hostaddr));
  145.     hostaddr.sin_family = AF_INET;
  146.     if ((inaddr = inet_addr(pargs.isolated_host)) != INADDR_NONE)
  147.         bcopy(&inaddr,&hostaddr.sin_addr,sizeof(inaddr));
  148.     else if ((hostp = gethostbyname(pargs.isolated_host)) != NULL)
  149.         bcopy(hostp->h_addr,&hostaddr.sin_addr,hostp->h_length);
  150.     else {
  151.         printf("%s: unknown host\r\n",pargs.isolated_host);
  152.         exit(1);
  153.     }
  154.     if ((servp = getservbyname(pargs.service_name,TCP_PROTO)) != NULL)
  155.         hostaddr.sin_port = servp->s_port;
  156.     else if (atoi(pargs.service_name) > 0)
  157.         hostaddr.sin_port = htons(atoi(pargs.service_name));
  158.     else {
  159.         printf("%s: invalid/unknown service name or port number\r\n", pargs.service_name);
  160.         exit(1);
  161.     }
  162. }

  163. /*-----------------------------------------------------------------*/

  164. /****************************************************************
  165. function:     daemonize
  166. description:  detach the server process from the current context,
  167.               creating a pristine, predictable environment in
  168.               which it will execute.
  169. arguments:    servfd file descriptor in use by server.
  170. return value: none.
  171. calls:        none.
  172. globals:      none.
  173. ****************************************************************/
  174. void daemonize (servfd)
  175. int servfd;
  176. {
  177.     int childpid, fd, fdtablesize;
  178.     /* ignore terminal I/O, stop signals */
  179.       signal(SIGTTOU,SIG_IGN);
  180.       signal(SIGTTIN,SIG_IGN);
  181.       signal(SIGTSTP,SIG_IGN);
  182.     /* fork to put us in the background (whether or not the user
  183.      specified '&' on the command line */
  184.     if ((childpid = fork()) < 0) {
  185.         fputs("failed to fork first child\r\n",stderr);
  186.         exit(1);
  187.       }
  188.     else if (childpid > 0)
  189.       exit(0); /* terminate parent, continue in child */
  190.       /* dissociate from process group */
  191.     if (setpgrp(0,getpid())<0) {
  192.         fputs("failed to become process group leader\r\n",stderr);
  193.         exit(1);
  194.     }
  195.     /* lose controlling terminal */
  196.     if ((fd = open("/dev/tty",O_RDWR)) >= 0) {
  197.         ioctl(fd,TIOCNOTTY,NULL);
  198.         close(fd);
  199.     }
  200.     /* close any open file descriptors */
  201.     for (fd = 0, fdtablesize = getdtablesize(); fd < fdtablesize; fd++)
  202.     if (fd != servfd)
  203.       close(fd);
  204.       /* set working directory to allow filesystems to be unmounted */
  205.       chdir("/");
  206.       /* clear the inherited umask */
  207.       umask(0);
  208.       /* setup zombie prevention */
  209.       signal(SIGCHLD,(Sigfunc *)reap_status);
  210.     }

  211. /****************************************************************
  212. function:       reap_status
  213. description:    handle a SIGCLD signal by reaping the exit status
  214.                 of the perished child, and discarding it.
  215. arguments:      none.
  216. return value:   none.
  217. calls:          none.
  218. globals:        none.
  219. ****************************************************************/
  220. void reap_status()
  221. {
  222.         int pid;
  223.         /* union wait status; */
  224.         int status;
  225.         while ((pid = wait3(&status,WNOHANG,NULL)) > 0)
  226.         ; /* loop while there are more dead children */
  227. }

  228. /****************************************************************
  229. function:      do_proxy
  230. description:   does the actual work of virtually connecting a
  231.                client to the telnet service on the  isolated host.
  232. arguments:     usersockfd socket to which the client is connected.
  233. return value:  none.
  234. calls:         none.
  235. globals:       reads hostaddr.
  236. ****************************************************************/
  237. void do_proxy (usersockfd)
  238. int usersockfd;
  239. {
  240.     int isosockfd;
  241.     fd_set rdfdset;
  242.     int connstat;
  243.     int iolen;
  244.     char buf[2048];
  245.     /* open a socket to connect to the isolated host */
  246.     if ((isosockfd = socket(AF_INET,SOCK_STREAM,0)) < 0)
  247.     errorout("failed to create socket to host");
  248.     /* attempt a connection */
  249.     connstat = connect(isosockfd,(struct sockaddr *) &hostaddr, sizeof(hostaddr));
  250.     switch (connstat) {
  251.     case 0:
  252.     break;
  253.     case ETIMEDOUT:
  254.     case ECONNREFUSED:
  255.     case ENETUNREACH:
  256.     strcpy(buf,sys_myerrlist[errno]);
  257.     strcat(buf,"\r\n");
  258.     write(usersockfd,buf,strlen(buf));
  259.     close(usersockfd);
  260.     exit(1);
  261.     /* die peacefully if we can't establish a connection */
  262.     break;
  263.     default:
  264.     errorout("failed to connect to host");
  265.     }
  266.     /* now we're connected, serve fall into the data echo loop */
  267.     while (1) {
  268.         /* Select for readability on either of our two sockets */
  269.         FD_ZERO(&rdfdset);
  270.         FD_SET(usersockfd,&rdfdset);
  271.         FD_SET(isosockfd,&rdfdset);
  272.     if (select(FD_SETSIZE,&rdfdset,NULL,NULL,NULL) < 0)
  273.       errorout("select failed");
  274.       /* is the client sending data? */
  275.     if (FD_ISSET(usersockfd,&rdfdset)) {
  276.         if ((iolen = read(usersockfd,buf,sizeof(buf))) <= 0)
  277.           break; /* zero length means the client disconnected */
  278.           write(isosockfd,buf,iolen);
  279.           /* copy to host -- blocking semantics */
  280.       }
  281.     /* is the host sending data? */
  282.     if (FD_ISSET(isosockfd,&rdfdset)) {
  283.         if ((iolen = read(isosockfd,buf,sizeof(buf))) <= 0)
  284.             break; /* zero length means the host disconnected */
  285.             write(usersockfd,buf,iolen);
  286.             /* copy to client -- blocking semantics */
  287.         }
  288.       }
  289.       /* we're done with the sockets */
  290.       close(isosockfd);
  291.       close(usersockfd);
  292.     }

  293. /****************************************************************
  294. function:    errorout
  295. description: displays an error message on the console and kills
  296.              the current process.
  297. arguments:   msg -- message to be displayed.
  298. return value: none -- does not return.
  299. calls:       none.
  300. globals:     none.
  301. ****************************************************************/
  302. void errorout (msg)
  303. char *msg;
  304. {
  305.     FILE *console;
  306.     console = fopen("/dev/console","a");
  307.     fprintf(console,"proxyd: %s\r\n",msg);
  308.     fclose(console);
  309.     exit(1);
  310. }

复制代码

server.zip

9.82 KB, 下载次数: 58

论坛徽章:
0
10 [报告]
发表于 2007-12-07 10:33 |只看该作者
原帖由 swordfish.cn 于 2007-12-4 22:52 发表
回楼上的同志,你用 -v 来编译?



回swordfish.cn,使用-v选项只是为了能看到gcc编译的时候查找了哪些库,因为这个程序是在链接的时候找不到相应的库。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP