Unix网络编程第三版源码编译

时间:2022-02-10 00:24:58
环境: $ cat /etc/issue Ubuntu 12.04.1 LTS \n \l
$ cat /proc/version Linux version 3.2.0-48-generic (buildd@komainu) (gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) ) #74-Ubuntu SMP Thu Jun 6 19:43:26 UTC 2013
$ uname -a Linux ubuntu-server 3.2.0-48-generic #74-Ubuntu SMP Thu Jun 6 19:43:26 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux

下载: $ git clone https://github.com/maxliaops/Unix-Network-Programming.git
配置: $ cd Unix-Network-Programming/ $ chmod 755 configure $ ./configure 主要的工作是检查系统是否有源码编译所依赖的各种资源(系统版本是否匹配、编译器、库文件、头文件以及结构体定义等等) checking build system type... x86_64-unknown-linux-gnu checking host system type... x86_64-unknown-linux-gnu checking for gcc... gcc checking for C compiler default output... a.out checking whether the C compiler works... yes checking whether we are cross compiling... no checking for suffix of executables... checking for suffix of object files... o checking whether we are using the GNU C compiler... yes checking whether gcc accepts -g... yes checking for gcc option to accept ANSI C... none needed checking for ranlib... ranlib checking for pthread_create in -lpthread... yes checking for t_open in -lnsl... no checking for library containing socket... none required checking for /usr/local/bind/lib/libbind.a... no checking for /home/liaops/libbind.a... no checking for /home/liaops/libresolv.a... no checking for res_init in -lresolv... no checking for t_open in -lxti... no checking for /home/liaops/libunp.a... no checking for /home/liaops/libunpxti.a... no checking how to run the C preprocessor... gcc -E checking for egrep... grep -E checking for ANSI C header files... yes checking for sys/types.h... yes checking for sys/socket.h... yes checking for sys/time.h... yes checking for time.h... yes checking for netinet/in.h... yes checking for arpa/inet.h... yes checking for errno.h... yes checking for fcntl.h... yes checking for netdb.h... yes checking for signal.h... yes checking for stdio.h... yes checking for stdlib.h... yes checking for string.h... yes checking for sys/stat.h... yes checking for sys/uio.h... yes checking for unistd.h... yes checking for sys/wait.h... yes checking for sys/un.h... yes checking for sys/param.h... yes checking for sys/select.h... yes checking for sys/sysctl.h... yes checking for poll.h... yes checking for sys/event.h... no checking for strings.h... yes checking for sys/ioctl.h... yes checking for sys/filio.h... no checking for sys/sockio.h... no checking for pthread.h... yes checking for net/if_dl.h... no checking for xti.h... no checking for xti_inet.h... no checking for netconfig.h... no checking for netdir.h... no checking for stropts.h... yes checking whether time.h and sys/time.h may both be included... yes checking if uint8_t defined... yes checking if int16_t defined... yes checking if uint16_t defined... yes checking if int32_t defined... yes checking if uint32_t defined... yes checking if size_t defined... yes checking if ssize_t defined... yes checking if socklen_t defined... yes checking if sa_family_t defined... yes checking if t_scalar_t defined... no checking if t_uscalar_t defined... yes checking for struct sockaddr.sa_len... no checking for struct sockaddr_storage... yes checking for struct sockaddr_storage.ss_family... yes checking for struct msghdr.msg_control... yes checking for struct ifreq.ifr_mtu... yes checking for getaddrinfo function prototype in netdb.h... yes checking for getnameinfo function prototype in netdb.h... yes checking for gethostname function prototype in unistd.h... yes checking for getrusage function prototype in sys/resource.h... yes checking for hstrerror function prototype in netdb.h... yes checking for if_nametoindex function prototype in net/if.h... yes checking for inet_aton function prototype in arpa/inet.h... yes checking for inet_pton function prototype in arpa/inet.h... yes checking for pselect function prototype in sys/select.h... yes checking for snprintf function prototype in stdio.h... yes checking for sockatmark function prototype in sys/socket.h... yes checking for struct addrinfo... yes checking for struct if_nameindex... yes checking for struct sockaddr_dl... no checking for struct timespec... yes checking for /dev/tcp... no checking for /dev/xti/tcp... no checking for /dev/streams/xtiso/tcp... no checking for bzero... yes checking for getaddrinfo... yes checking for gethostname... yes checking for gethostbyname2... yes checking for gethostbyname_r... yes checking for getnameinfo... yes checking for hstrerror... yes checking for if_nametoindex... yes checking for inet_aton... yes checking for inet_pton... yes checking for inet6_rth_init... yes checking for kqueue... no checking for kevent... no checking for mkstemp... yes checking for poll... yes checking for pselect... yes checking for snprintf... yes checking for sockatmark... yes checking for vsnprintf... yes checking for IPv4 support... yes checking for IPv6 support... yes checking for Unix domain sockets... yes checking for multicast support... yes checking for -I/home/liaops/doc/unp2ev1/src/include... no configure: creating ./config.status config.status: creating Makefile config.status: creating Make.defines config.status: creating config.h


编译库:
编译所有例程都需要用到的基础库 $ cd lib $ make
得到静态库文件:libudp.a
查看符号表 (主要是想看一下这个库的各个源文件调用了哪些Linux系统调用) $ nm -g libunp.a
从中可以发现以下几个文件比较重要,主要是对常用的API进行了一层包装。 wrapsock.o:     对套接字socket的包装     accept     bind     connect     err_quit     err_sys     getenv     getpeername     getsockname     getsockopt     inet6_rth_add     inet6_rth_getaddr     inet6_rth_init     inet6_rth_reverse     inet6_rth_segments     inet6_rth_space     listen     poll     recv     recvfrom     recvmsg     select     send     sendmsg     sendto     setsockopt     shutdown     sockatmark     socket     socketpair     strtol wrapstdio.o:    对标准IO库中文件相关函数的包装     fclose     fdopen     ferror     fgets     fopen     fputs wrappthread.o:  对线程库pthread的包装     pthread_cond_broadcast     pthread_cond_signal     pthread_cond_timedwait     pthread_cond_wait     pthread_create     pthread_detach     pthread_join     pthread_key_create     pthread_kill     pthread_mutex_init     pthread_mutex_lock     pthread_mutex_unlock     pthread_mutexattr_init     pthread_mutexattr_setpshared     pthread_once     pthread_setspecific wrapunix.o:     对其他常用Linux/Unix系统调用的包装     __strdup     calloc     close     dup2     err_quit     err_sys     fcntl     fork     gettimeofday     ioctl     malloc     mkstemp     mmap     open     pipe     read     sigaddset     sigdelset     sigemptyset     sigfillset     sigismember     sigpending     sigprocmask     sysconf     sysctl     unlink     wait     waitpid     write
问题:为什么要对这些API接口进行包装,是否多此一举?



继续编译基本库 $ cd ../libfree/ $ make gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o in_cksum.o in_cksum.c gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o inet_ntop.o inet_ntop.c inet_ntop.c: In function ‘inet_ntop’: inet_ntop.c:61: error: argument ‘size’ doesn’t match prototype /usr/include/arpa/inet.h:65: error: prototype declaration make: *** [inet_ntop.o] Error 1
出现错误!
Fix: inet_ntop.c第61行 size_t size ->改成 socklen_t size)
再次编译 $ make gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o inet_ntop.o inet_ntop.c gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o inet_pton.o inet_pton.c ar rv ../libunp.a in_cksum.o inet_ntop.o inet_pton.o a - in_cksum.o a - inet_ntop.o a - inet_pton.o ranlib ../libunp.a
貌似这次编译的内容并到了libunp.a中,没有生成新的库文件。

$ cd ../libgai $ make ar rv ../libunp.a ranlib ../libunp.a

拷贝生成的库文件到系统库目录 $ cd .. $ sudo cp libunp.a /usr/lib $ sudo cp libunp.a /usr/lib32
以后编译代码的时候加上-lunp链接我们的库。
修改unp.h并将其和config.h拷贝到/usr/include中



编译并测试一个基本的客户端例程
$ cd intro/ $ make daytimetcpcli gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o daytimetcpcli.o daytimetcpcli.c gcc -I../lib -g -O2 -D_REENTRANT -Wall -o daytimetcpcli daytimetcpcli.o ../libunp.a -lpthread
编译成功后,在当前目录会生成可执行镜像daytimetcpcli
运行daytimetcpcli $ ./daytimetcpcli usage: a.out <IPaddress>
$ ./daytimetcpcli 127.0.0.1 connect error: Connection refused
Fix: 开启daytime服务
$ make daytimetcpsrv gcc -I../lib -g -O2 -D_REENTRANT -Wall -c -o daytimetcpsrv.o daytimetcpsrv.c gcc -I../lib -g -O2 -D_REENTRANT -Wall -o daytimetcpsrv daytimetcpsrv.o ../libunp.a -lpthread
sudo ./daytimetcpsrv &
再次运行daytimetcpcli $ ./daytimetcpcli 127.0.0.1 Mon Mar 3 22:47:35 2014