unix网络编程卷1:套接字联网 源码编译

QUICK AND DIRTY

Execute the following from the src/ directory:

一:

./configure    # try to figure out all 

结果是:

........
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/xiahuixia/doc/unp2ev1/src/include... no
configure: creating ./config.status
config.status: creating Makefile
config.status: creating Make.defines
config.status: creating config.h

configure之后,多出了Makefile, Makefile.defines, config.h文件

二:

 cd lib         # build the basic library that all programs need
 make           # use "gmake" everywhere on BSD/OS systems

注:lib下的makefile文件内容

include ../Make.defines

all:    ${LIB_OBJS}
        ar rv ${LIBUNP_NAME} $?
        ${RANLIB} ${LIBUNP_NAME}

clean:
        rm -f ${PROGS} ${CLEANFILES}

注:通过configure生成的Make.defines文件是

#
# This file is generated by autoconf from "Make.defines.in".
#
# This is the "Make.defines" file that almost every "Makefile" in the
# source directories below this directory include.
# The "../" in the pathnames actually refer to this directory, since
# "make" is executed in all the subdirectories of this directory.
#
# System = x86_64-unknown-linux-gnu

CC = gcc
CFLAGS = -I../lib -g -O2 -D_REENTRANT -Wall
LIBS = ../libunp.a -lpthread
LIBS_XTI = ../libunpxti.a ../libunp.a -lpthread
RANLIB = ranlib

# Following is the main library, built from all the object files
# in the lib/ and libfree/ directories.
LIBUNP_NAME = ../libunp.a

# Following is the XTI library, built from all the object files
# in the libxti/ directory.
LIBUNPXTI_NAME = ../libunpxti.a

# Following are all the object files to create in the lib/ directory.
LIB_OBJS =  connect_nonb.o connect_timeo.o daemon_inetd.o daemon_init.o dg_cli.o dg_echo.o error.o get_ifi_info.o gf_time.o host_serv.o family_to_level.o mcast_leave.o mcast_join.o mcast_get_if.o mcast_get_loop.o mcast_get_ttl.o mcast_set_if.o mcast_set_loop.o mcast_set_ttl.o my_addrs.o read_fd.o readline.o readn.o readable_timeo.o rtt.o signal.o signal_intr.o sock_bind_wild.o sock_cmp_addr.o sock_cmp_port.o sock_ntop.o sock_ntop_host.o sock_get_port.o sock_set_addr.o sock_set_port.o sock_set_wild.o sockfd_to_family.o str_cli.o str_echo.o tcp_connect.o tcp_listen.o tv_sub.o udp_client.o udp_connect.o udp_server.o wraplib.o wrapsock.o wrapstdio.o wrappthread.o wrapunix.o write_fd.o writen.o writable_timeo.o

# Following are all the object files to create in the libfree/ directory.
LIBFREE_OBJS =  in_cksum.o inet_ntop.o inet_pton.o

# Following are all the object files to create in the libgai/ directory.
LIBGAI_OBJS = 

# Following are all the object files to create in the libroute/ directory.
LIBROUTE_OBJS = get_rtaddrs.o if_indextoname.o if_nameindex.o if_nametoindex.o net_rt_iflist.o net_rt_dump.o sock_masktop.o

# Following are all the object files to create in the libxti/ directory.
LIBXTI_OBJS =  wrapxti.o xti_accept.o xti_flags_str.o xti_getopt.o xti_ntop.o xti_ntop_host.o xti_rdwr.o xti_setopt.o xti_str_opts.o xti_tlook_str.o

CLEANFILES = core core.* *.core *.o temp.* *.out typescript*         *.lc *.lh *.bsdi *.sparc *.uw

结果是:

[email protected]3437:~/unix/unpv13e/lib$ make
gcc -I../lib -g -O2 -D_REENTRANT -Wall   -c -o connect_nonb.o connect_nonb.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall   -c -o connect_timeo.o connect_timeo.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall   -c -o daemon_inetd.o daemon_inetd.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall   -c -o daemon_init.o daemon_init.c
daemon_init.c: In function ‘daemon_init’:
daemon_init.c:34:7: warning: ignoring return value of ‘chdir’, declared with attribute warn_unused_result [-Wunused-result]
  chdir("/");    /* change working directory */
       ^
gcc -I../lib -g -O2 -D_REENTRANT -Wall   -c -o dg_cli.o dg_cli.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall   -c -o dg_echo.o dg_echo.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall   -c -o error.o error.c
error.c: In function ‘err_doit’:
error.c:102:3: warning: format not a string literal and no format arguments [-Wformat-security]
   syslog(level, buf);
   ^
gcc -I../lib -g -O2 -D_REENTRANT -Wall   -c -o get_ifi_info.o get_ifi_info.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall   -c -o gf_time.o gf_time.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall   -c -o host_serv.o host_serv.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall   -c -o family_to_level.o family_to_level.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall   -c -o mcast_leave.o mcast_leave.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall   -c -o mcast_join.o mcast_join.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall   -c -o mcast_get_if.o mcast_get_if.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall   -c -o mcast_get_loop.o mcast_get_loop.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall   -c -o mcast_get_ttl.o mcast_get_ttl.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall   -c -o mcast_set_if.o mcast_set_if.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall   -c -o mcast_set_loop.o mcast_set_loop.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall   -c -o mcast_set_ttl.o mcast_set_ttl.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall   -c -o my_addrs.o my_addrs.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall   -c -o read_fd.o read_fd.c
read_fd.c: In function ‘read_fd’:
read_fd.c:45:3: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
   *recvfd = *((int *) CMSG_DATA(cmptr));
   ^
gcc -I../lib -g -O2 -D_REENTRANT -Wall   -c -o readline.o readline.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall   -c -o readn.o readn.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall   -c -o readable_timeo.o readable_timeo.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall   -c -o rtt.o rtt.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall   -c -o signal.o signal.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall   -c -o signal_intr.o signal_intr.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall   -c -o sock_bind_wild.o sock_bind_wild.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall   -c -o sock_cmp_addr.o sock_cmp_addr.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall   -c -o sock_cmp_port.o sock_cmp_port.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall   -c -o sock_ntop.o sock_ntop.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall   -c -o sock_ntop_host.o sock_ntop_host.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall   -c -o sock_get_port.o sock_get_port.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall   -c -o sock_set_addr.o sock_set_addr.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall   -c -o sock_set_port.o sock_set_port.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall   -c -o sock_set_wild.o sock_set_wild.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall   -c -o sockfd_to_family.o sockfd_to_family.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall   -c -o str_cli.o str_cli.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall   -c -o str_echo.o str_echo.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall   -c -o tcp_connect.o tcp_connect.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall   -c -o tcp_listen.o tcp_listen.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall   -c -o tv_sub.o tv_sub.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall   -c -o udp_client.o udp_client.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall   -c -o udp_connect.o udp_connect.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall   -c -o udp_server.o udp_server.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall   -c -o wraplib.o wraplib.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall   -c -o wrapsock.o wrapsock.c
wrapsock.c: In function ‘Inet6_rth_space’:
wrapsock.c:81:2: warning: implicit declaration of function ‘inet6_rth_space’ [-Wimplicit-function-declaration]
  ret = inet6_rth_space(type, segments);
  ^
wrapsock.c: In function ‘Inet6_rth_init’:
wrapsock.c:93:2: warning: implicit declaration of function ‘inet6_rth_init’ [-Wimplicit-function-declaration]
  ret = inet6_rth_init(rthbuf, rthlen, type, segments);
  ^
wrapsock.c:93:6: warning: assignment makes pointer from integer without a cast [enabled by default]
  ret = inet6_rth_init(rthbuf, rthlen, type, segments);
      ^
wrapsock.c: In function ‘Inet6_rth_add’:
wrapsock.c:103:2: warning: implicit declaration of function ‘inet6_rth_add’ [-Wimplicit-function-declaration]
  if (inet6_rth_add(rthbuf, addr) < 0)
  ^
wrapsock.c: In function ‘Inet6_rth_reverse’:
wrapsock.c:110:2: warning: implicit declaration of function ‘inet6_rth_reverse’ [-Wimplicit-function-declaration]
  if (inet6_rth_reverse(in, out) < 0)
  ^
wrapsock.c: In function ‘Inet6_rth_segments’:
wrapsock.c:119:2: warning: implicit declaration of function ‘inet6_rth_segments’ [-Wimplicit-function-declaration]
  ret = inet6_rth_segments(rthbuf);
  ^
wrapsock.c: In function ‘Inet6_rth_getaddr’:
wrapsock.c:131:2: warning: implicit declaration of function ‘inet6_rth_getaddr’ [-Wimplicit-function-declaration]
  ret = inet6_rth_getaddr(rthbuf, idx);
  ^
wrapsock.c:131:6: warning: assignment makes pointer from integer without a cast [enabled by default]
  ret = inet6_rth_getaddr(rthbuf, idx);
      ^
gcc -I../lib -g -O2 -D_REENTRANT -Wall   -c -o wrapstdio.o wrapstdio.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall   -c -o wrappthread.o wrappthread.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall   -c -o wrapunix.o wrapunix.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall   -c -o write_fd.o write_fd.c
write_fd.c: In function ‘write_fd’:
write_fd.c:24:2: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
  *((int *) CMSG_DATA(cmptr)) = sendfd;
  ^
gcc -I../lib -g -O2 -D_REENTRANT -Wall   -c -o writen.o writen.c
gcc -I../lib -g -O2 -D_REENTRANT -Wall   -c -o writable_timeo.o writable_timeo.c
ar rv ../libunp.a connect_nonb.o connect_timeo.o daemon_inetd.o daemon_init.o dg_cli.o dg_echo.o error.o get_ifi_info.o gf_time.o host_serv.o family_to_level.o mcast_leave.o mcast_join.o mcast_get_if.o mcast_get_loop.o mcast_get_ttl.o mcast_set_if.o mcast_set_loop.o mcast_set_ttl.o my_addrs.o read_fd.o readline.o readn.o readable_timeo.o rtt.o signal.o signal_intr.o sock_bind_wild.o sock_cmp_addr.o sock_cmp_port.o sock_ntop.o sock_ntop_host.o sock_get_port.o sock_set_addr.o sock_set_port.o sock_set_wild.o sockfd_to_family.o str_cli.o str_echo.o tcp_connect.o tcp_listen.o tv_sub.o udp_client.o udp_connect.o udp_server.o wraplib.o wrapsock.o wrapstdio.o wrappthread.o wrapunix.o write_fd.o writen.o writable_timeo.o
ar: creating ../libunp.a
a - connect_nonb.o
a - connect_timeo.o
a - daemon_inetd.o
a - daemon_init.o
a - dg_cli.o
a - dg_echo.o
a - error.o
a - get_ifi_info.o
a - gf_time.o
a - host_serv.o
a - family_to_level.o
a - mcast_leave.o
a - mcast_join.o
a - mcast_get_if.o
a - mcast_get_loop.o
a - mcast_get_ttl.o
a - mcast_set_if.o
a - mcast_set_loop.o
a - mcast_set_ttl.o
a - my_addrs.o
a - read_fd.o
a - readline.o
a - readn.o
a - readable_timeo.o
a - rtt.o
a - signal.o
a - signal_intr.o
a - sock_bind_wild.o
a - sock_cmp_addr.o
a - sock_cmp_port.o
a - sock_ntop.o
a - sock_ntop_host.o
a - sock_get_port.o
a - sock_set_addr.o
a - sock_set_port.o
a - sock_set_wild.o
a - sockfd_to_family.o
a - str_cli.o
a - str_echo.o
a - tcp_connect.o
a - tcp_listen.o
a - tv_sub.o
a - udp_client.o
a - udp_connect.o
a - udp_server.o
a - wraplib.o
a - wrapsock.o
a - wrapstdio.o
a - wrappthread.o
a - wrapunix.o
a - write_fd.o
a - writen.o
a - writable_timeo.o
ranlib ../libunp.a

三:

  cd ../libfree  # continue building the basic library
  make

结果报错:

[email protected]-Inspiron-3437:~/unix/unpv13e/libfree$ make
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:60:9: error: argument ‘size’ doesn’t match prototype
  size_t size;
         ^
In file included from inet_ntop.c:27:0:
/usr/include/arpa/inet.h:64:20: error: prototype declaration
 extern const char *inet_ntop (int __af, const void *__restrict __cp,
                    ^
make: *** [inet_ntop.o] Error 1

解决方法:

经过查询inet_ntop.c 和 inet.h 文件发现在头文件中inet_ntop的原型声明与inet_ntop.c中的该函数实现原型的第三个参数类型不一致

inet.h 和 inet_ntop.c中的函数原型如下:



//inet.h
__const char *inet_ntop (int __af, __const void *__restrict __cp, char *__restrict __buf, socklen_t __len) __THROW;
//inet_ntop.c
const char *
inet_ntop(int af, const void *src, char *dst, size_t size);

其中第三个参数类型分别为socklen_t和size_t,解决方案为在inet_ntop.c中加入以下代码:

#define size_t socklen_t

五:

cd ../libroute # only if your system supports 4.4BSD style routing sockets
make           # only if your system supports 4.4BSD style routing sockets

cd ../libxti   # only if your system supports XTI
make           # only if your system supports XTI

cd ../intro    # build and test a basic client program
make daytimetcpcli
./daytimetcpcli 127.0.0.1

If all that works, you’re all set to start compiling individual programs.

Notice that all the source code assumes tabs every 4 columns, not 8.

MORE DETAILS

  1. If you need to make any changes to the “unp.h” header, notice that it

    is a hard link in each directory, so you only need to change it once.

  2. Go into the “lib/” directory and type “make”. This builds the library

    “libunp.a” that is required by almost all of the programs. There may

    be compiler warnings (see NOTES below). This step is where you’ll find

    all of your system’s dependencies, and you must just update your cf/

    files from step 1, rerun “config” and do this step again.

  3. Go into the “libfree/” directory and type “make”. This adds to the

    “libunp.a” library. The files in this directory do not #include

    the “unp.h” header, as people may want to use these functions

    independent of the book’s examples.

  4. Once the library is made from steps 5 and 6, you can then go into any

    of the source code directories and make whatever program you are

    interested in. Note that the horizontal rules at the beginning and

    end of each program listing in the book contain the directory name and

    filename.

    BEWARE: Not all programs in each directory will compile on all systems

    (e.g., the file src/advio/recvfromflags.c will not compile unless your

    system supports the IP_RECVDSTADDR socket option). Also, not all files

    in each directory are included in the book. Beware of any files with

    “test” in the filename: they are probably a quick test program that I

    wrote to check something, and may or may not work.

NOTES

  • Many systems do not have correct function prototypes for the socket

    functions, and this can cause many warnings during compilation.

    For example, Solaris 2.5 omits the “const” from the 2nd argument

    to connect(). Lots of systems use “int” for the length of socket

    address structures, while Posix.1g specifies “size_t”. Lots of

    systems still have the pointer argument to [sg]etsockopt() as a

    “char ” instead of a “void “, and this also causes warnings.

  • SunOS 4.1.x: If you are using Sun’s acc compiler, you need to run

    the configure program as

    CC=acc CFLAGS=-w CPPFLAGS=-w ./configure
    

    Failure to do this results in numerous system headers (

COMMON DIFFERENCES

These are the common differences that I see in various headers that are

not “yet” at the level of Posix.1g or X/Open XNS Issue 5.

  • getsockopt() and setsockopt(): 5th argument is not correct type.
  • t_bind(): second argument is missing “const”.
  • t_connect(): second argument is missing “const”.
  • t_open(): first argument is missing “const”.
  • t_optmsmg(): second argument is missing “const”.
  • If your
时间: 2024-10-17 18:21:29

unix网络编程卷1:套接字联网 源码编译的相关文章

Unix网络编程--卷一:套接字联网API 读书笔记

UNIX网络编程--卷一:套接字联网API 本书面对的读者是那些希望自己编写的程序能够使用成为套接字(socket)的API进行彼此通信的人. 目录: 1.简介 2.传输层:TCP.UDP和SCTP 3.套接字编程简介 4.基本TCP套接字编程 5.TCP客户/服务器程序例子 6.I/O复用:select和poll函数 7.套接字选项 8.基本UDP套接字编程 9.基本SCTP套接字编程 10.SCTP客户/服务器程序例子 11.名字与地址转换 12.IPV4与IPV6互操作性 13.守护进程和

UNIX网络编程:socket套接字(TCP与UDP)

套接字简介: 套接字是网络编程中的一种通信机制,是支持TCP/IP的网络通信的基本操作单元,可以看做是不同主机之间的进程进行双向通信的端点,简单的说就是通信的两方的一种约定,用套接字中的相关函数来完成通信过程.应用层通过传输层进行数据通信时,TCP和UDP会遇到同时为多个应用程序进程提供并发服务的问题.凭借这种机制,客户/服务器系统的开发工作既可以在本地单机上进行,也可以跨网络进行,Linux所提供的功能(如打印服务,ftp等)通常都是通过套接字来进行通信的,套接字的创建和使用与管道是有区别的,

Unix网络编程随手记——套接字接口函数

套接字接口(socket interface)是一组函数,它们和Unix I/O函数结合起来,用以创建网络应用.大多数现代系统上都实现套接字接口,包括所有的Unix变种.Windows和Macintosh. 1.套接字的基本结构 struct sockaddr 这个结构用来存储套接字地址. 数据定义: 1 struct sockaddr 2 { 3 unsigned short sa_family; /* address族, AF_xxx */ 4 char sa_data[14]; /* 14

【Unix网络编程】chapter3 套接字编程简介

chapter3套接字编程简介3.1 概述 地址转换函数在地址的文本表达和他们存放在套接字地址结构中的二进制值之间进行转换.多数现存的IPv4代码使用inet_addr和inet_ntoa这两个函数,不过这两个新函数inet_pton和inet_ntop同时适用于IPv4和IPv6. 3.2 套接字地址结构 sockaddr_ 3.2.1 IPv4套接字地址结构 IPv4套接字地址结构通常也称为"网际套接字地址结构",它以sockaddr_in命令,定义在<netinet/in.

【Unix网络编程】chapter3套接字编程简介

3.1 概述 地址转换函数在地址的文本表达和他们存放在套接字地址结构中的二进制值之间进行转换.多数现存的IPv4代码使用inet_addr和inet_ntoa这两个函数,不过这两个新函数inet_pton和inet_ntop同时适用于IPv4和IPv6. 3.2 套接字地址结构 sockaddr_ 3.2.1 IPv4套接字地址结构 IPv4套接字地址结构通常也称为"网际套接字地址结构",它以sockaddr_in命令,定义在<netinet/in.h>头文件中 struc

Unix网络编程 高级IO套接字设置超时

我们知道,对于一个套接字的读写(read/write)操作默认是阻塞的,如果当前套接字还不可读/写,那么这个操作会一直阻塞下去,这样对于一个需要高性能的服务器来说,是不能接受的.所以,我们可以在进行读写操作的时候可以指定超时值,这样就读写操作就不至于一直阻塞下去. 在涉及套接字的I/O操作上设置超时的方法有三种: 1:调用alarm,它在指定的超时期满时产生SIGALRM信号.这个方法涉及信号处理,而信号处理在不同的实现上存在差异,而且可能干扰进程中现有的alarm调用. 2:在select中阻

[转载] 读《UNIX网络编程 卷1:套接字联网API》

原文: http://cstdlib.com/tech/2014/10/09/read-unix-network-programming-1/ 文章写的很清楚, 适合初学者 最近看了<UNIX网络编程 卷1:套接字联网API>, 英文名叫Unix Network Programming啦,后来上网查了查, 一般都叫UNP逼格会高一点, 就像APUE一样. 他们的作者都是W. Richard Stevens. 另外,他也是TCP/IP Illustrated的作者. 靠,看完作者简介,简直崇拜得

UNIX网络编程 卷1:套接字联网API

这篇是计算机类的优质预售推荐>>>><UNIX网络编程 卷1:套接字联网API> UNIX和网络专家W. Richard Stevens的传世之作,世界著名网络专家Bill Fenner和Andrew M. Rudoff执笔新版 编辑推荐 这是一部传世之作!顶级网络编程专家Bill Fenner和Andrew M. Rudoff应邀执笔,对W. Richard Stevens的经典作品进行修订.书中吸纳了近几年网络技术的发展,增添了IPv6.SCTP协议和密钥管理套接字

Linux网络编程:原始套接字的魔力【上】

基于原始套接字编程 在开发面向连接的TCP和面向无连接的UDP程序时,我们所关心的核心问题在于数据收发层面,数据的传输特性由TCP或UDP来保证: 也就是说,对于TCP或UDP的程序开发,焦点在Data字段,我们没法直接对TCP或UDP头部字段进行赤裸裸的修改,当然还有IP头.换句话说,我们对它们头部操作的空间非常受限,只能使用它们已经开放给我们的诸如源.目的IP,源.目的端口等等. 今天我们讨论一下原始套接字的程序开发,用它作为入门协议栈的进阶跳板太合适不过了.OK闲话不多说,进入正题. 原始