UNIX网络编程学习


unix网络编程学习

最近抽时间学习UNIX网络编程,通过网络和书中的知识将以前落下的内容尽量补上来,因为以前基本上做windows相关开发,用到的网络方便的技术比较少,也没有进行深入研究,linux和网络编程这块是个短板,看书然后写一下例子程序,这期间一定会遇到各种问题,问题涉及环境搭建、网络编程、编译器、操作系统等不同方面,力求通过解决这些问题来建立起自己的“技术知识库”。

1.环境的搭建

.在执行例子之前,需要对于环境进行搭建(否则会出现各种undefined reference的问题);以下是网上查找以及自己领悟的一点点东西:我用的是CentOS系统,前期自己装了编译器,版本为4.4.7;

下载源码:我使用的是unpv13e.tar.gz ,解压到本地,按照编译其他源码类似的方式进行编译安装:

1) 运行configure并make

<pre name="code" class="plain">cd unp13e
chmod u+x configure
./configure

cd lib
make

 2)生成类库和函数库 

cd libfree
make 

cd lib gai
make
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

打开inet_ntop.c文件,在第61行,可以发现size是有问题的,打开inet.h,对比函数原型,发现size应该改为socklen_t 即可(在64位系统上,socklen_t和size_t大小不一样,系统差异带来的问题)

 extern __const char *inet_ntop (int __af, __const void *__restrict __cp,char *__restrict __buf, socklen_t __len) __THROW;

经过上述步骤之后,会生成libunp.a的静态库,为了以后的使用,最好将这个库加入到系统常用库目录中,避免编译路径的问题

3)拷贝库文件到lib目录

<pre name="code" class="plain">sudo cp libunp.a /usr/lib
sudo cp libunp.a /usr/lib64

 使用root用户或者添加sudo 

在lib/unp.h中,修改include  config.h的路径,改为:

#include “config.h”
4)拷贝头文件到/usr/include/

sudo cp lib/unp.h /usr/include
sudo cp config.h /usr/include

第四步主要是为了以后构建程序方便;

5)编译源代码

cd ./intro
gcc -o xxxx xxxx.c -lunp

这里会有个问题,如果代码中使用了err_sys、err_quit等错误输出,就会报was not declared的错误,这是因为编译器找不到函数这些函数是坐着自己封装的,需要我们在代码中加入,

具体是在/usr/inlcude目录下创建一个xxxx.h文件,拷贝以下内容:

#include "apue.h"  
#include <errno.h>      /* for definition of errno */  
#include <stdarg.h>     /* ISO C variable aruments */  
  
static void err_doit(int, int, const char *, va_list);  
  
/*  
* Nonfatal error related to a system call.  
* Print a message and return.  
*/  
void  err_ret(const char *fmt, ...)  
{  
    va_list     ap;  
  
    va_start(ap, fmt);  
    err_doit(1, errno, fmt, ap);  
    va_end(ap);  
}  
  
/*  
* Fatal error related to a system call.  
* Print a message and terminate.  
*/  
void  err_sys(const char *fmt, ...)  
{  
    va_list     ap;  
  
    va_start(ap, fmt);  
    err_doit(1, errno, fmt, ap);  
    va_end(ap);  
    exit(1);  
}  
  
/*  
* Fatal error unrelated to a system call.  
* Error code passed as explict parameter.  
* Print a message and terminate.  
*/  
void  err_exit(int error, const char *fmt, ...)  
{  
    va_list     ap;  
  
    va_start(ap, fmt);  
    err_doit(1, error, fmt, ap);  
    va_end(ap);  
    exit(1);  
}  
  
/*  
* Fatal error related to a system call.  
* Print a message, dump core, and terminate.  
*/  
void  err_dump(const char *fmt, ...)  
{  
    va_list     ap;  
  
    va_start(ap, fmt);  
    err_doit(1, errno, fmt, ap);  
    va_end(ap);  
    abort();        /* dump core and terminate */  
    exit(1);        /* shouldn't get here */  
}  
  
/*  
* Nonfatal error unrelated to a system call.  
* Print a message and return.  
*/  
void  err_msg(const char *fmt, ...)  
{  
    va_list     ap;  
  
    va_start(ap, fmt);  
    err_doit(0, 0, fmt, ap);  
    va_end(ap);  
}  
  
/*  
* Fatal error unrelated to a system call.  
* Print a message and terminate.  
*/  
void  
err_quit(const char *fmt, ...)  
{  
    va_list     ap;  
  
    va_start(ap, fmt);  
    err_doit(0, 0, fmt, ap);  
    va_end(ap);  
    exit(1);  
}  
  
/*  
* Print a message and return to caller.  
* Caller specifies "errnoflag".  
*/  
static void  err_doit(int errnoflag, int error, const char *fmt, va_list ap)  
{  
    char    buf[MAXLINE];  
   vsnprintf(buf, MAXLINE, fmt, ap);  
   if (errnoflag)  
       snprintf(buf+strlen(buf), MAXLINE-strlen(buf), ": %s",  
         strerror(error));  
   strcat(buf, " ");  
   fflush(stdout);     /* in case stdout and stderr are the same */  
   fputs(buf, stderr);  
   fflush(NULL);       /* flushes all stdio output streams */  
} 

注意apue.h是作者写的头文件,需要下载,我下载的是最新版apue.3e,不需要修改里面的内容,直接

sudo cp apue.3e/inlcude/apue.h /usr/include/
再编译程序应该就没有问题了。
如果出现下面的错误提示:

/tmp/ccA6KxDT.o:(.eh_frame+0x12): undefined reference to `__gxx_personality_v0' collect2: ld returned 1 exit status
这是因为文件后缀名称引起的,我当时写的代码是.cpp,使用gcc编译不加 -lstdc++ 就会出现这个问题;后来查了查,发现gcc编译cpp文件,但是在链接的时候,没有链接到c++的标准库,而-lstdc++对应的就是标准的c++库;


环境搭建不难,遇到问题通过分析也能找到原因,在分析问题的过程中,会涉及的各个方面,比如编译器,操作系统等等,都是值得发掘的。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值