板凳-------unix 网络编程 卷1-1简介

unix网络编程进程通信 unpipc.h

https://blog.csdn.net/u010527630/article/details/33814377?spm=1001.2014.3001.5502
订阅专栏
1>解压源码unpv22e.tar.gz。
$tar zxvf unpv22e.tar.gz //这样源码就被解压到当前的目录下了
2>运行configure脚本,以生成正确的Makefile。为什么steven不直接写成Makefile,其实很简单,不同平台的Makefile不同,所以
直接写个脚本,然后在不同的平台上运行改脚本,该脚本会根据当前的平台生存正确的Makefile。
. / c o n f i g u r e / / 当前目录为源码的解压后的目录 3 > ./configure //当前目录为源码的解压后的目录 3> ./configure//当前目录为源码的解压后的目录3>cd lib
$make //编译,以生产lib文件

4>注释…再次make


5>拷贝unpipc.h和config.h到/usr/include下。同时修改unppic.h的第7行的config.h的路径为"config.h"。
拷贝libunpipc.a文件至/usr/lib和/usr/lib64下。
6>修改Make.defines。如果要使用Makefile文件的话,可以模仿steven先生的Makefile,不过他的Makefile的变量是Make.defines
里定义的,其中就有lib文件的路径,修改lib*.a文件的路为/usr/lib/lib*.a。
至此大功告成!可以像使用标准的头文件和库文件一样的使用steven的文件。使用steven的头文件并不难,难的是我不知道编译相关的知识而已。

unix 第一章 简介

1.1 概述
焦点是TCP/IP协议族,也称为网际协议族
安装程序
Unix NetWork Programming——环境搭建&第三版源码编译

1.(base) wannian07@wannian07-PC:~$  git clone https://github.com/maxliaops/Unix-Network-Programming.git 
正克隆到 'Unix-Network-Programming'...
remote: Enumerating objects: 782, done.
remote: Total 782 (delta 0), reused 0 (delta 0), pack-reused 782
接收对象中: 100% (782/782), 579.66 KiB | 5.00 KiB/s, 完成.
处理 delta 中: 100% (115/115), 完成.
2.(base) wannian07@wannian07-PC:~$ cd Unix-Network-Programming/ 
3.(base) wannian07@wannian07-PC:~/Unix-Network-Programming$ chmod 755 configure
4.(base) wannian07@wannian07-PC:~/Unix-Network-Programming$ ./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/wannian07/libbind.a... no
checking for /home/wannian07/libresolv.a... no
checking for res_init in -lresolv... no
checking for t_open in -lxti... no
checking for /home/wannian07/libunp.a... no
checking for /home/wannian07/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... yes
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/wannian07/doc/unp2ev1/src/include... no
configure: creating ./config.status
config.status: creating Makefile
config.status: creating Make.defines
config.status: creating config.h
5.(base) wannian07@wannian07-PC:~/Unix-Network-Programming$ cd lib
6.(base) wannian07@wannian07-PC:~/Unix-Network-Programming/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
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
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:8: 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:8: 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 [-Wint-conversion]ret = inet6_rth_init(rthbuf, rthlen, type, segments);^
wrapsock.c: In function ‘Inet6_rth_add’:
wrapsock.c:103:6: 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:6: 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:8: 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:8: 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 [-Wint-conversion]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: 正在创建 ../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
7.(base) wannian07@wannian07-PC:~/Unix-Network-Programming/lib$ nm -g libunp.a 
nm: libunp.a:无此文件
8.(base) wannian07@wannian07-PC:~/Unix-Network-Programming/lib$ cd ../libfree/ 
9.(base) wannian07@wannian07-PC:~/Unix-Network-Programming/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
/usr/include/arpa/inet.h: In function ‘inet_ntop’:
inet_ntop.c:152:23: warning: ‘best.len’ may be used uninitialized in this function [-Wmaybe-uninitialized]if (best.base == -1 || cur.len > best.len)~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~
inet_ntop.c:123:28: note: ‘best.len’ was declared herestruct { int base, len; } best, cur;^~~~
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
(base) wannian07@wannian07-PC:~/Unix-Network-Programming/libfree$ cd ../libgai 
(base) wannian07@wannian07-PC:~/Unix-Network-Programming/libgai$ make
ar rv ../libunp.a 
ranlib ../libunp.a
10.(base) wannian07@wannian07-PC:~/Unix-Network-Programming/libgai$ cd ..
11.(base) wannian07@wannian07-PC:~/Unix-Network-Programming$ sudo cp libunp.a /usr/lib
[sudo] wannian07 的密码:
12.(base) wannian07@wannian07-PC:~/Unix-Network-Programming$ sudo cp libunp.a /usr/lib32 
13.(base) wannian07@wannian07-PC:~/Unix-Network-Programming$  cd intro/ 
14.(base) wannian07@wannian07-PC:~/Unix-Network-Programming/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
15.(base)wannian07@wannian07-PC:~/Unix-Network-Programming/intro$ ./daytimetcpcli 
usage: a.out <IPaddress>
16.(base) wannian07@wannian07-PC:~/Unix-Network-Programming/intro$  ./daytimetcpcli 127.0.0.1 
connect error: Connection refused
17.(base) wannian07@wannian07-PC:~/Unix-Network-Programming/intro$ 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
18.(base) wannian07@wannian07-PC:~/Unix-Network-Programming/intro$ sudo ./daytimetcpsrv & 
[1] 13902
19.	(base) wannian07@wannian07-PC:~/Unix-Network-Programming/intro$ ./daytimetcpcli 127.0.0.1 
Sun Jun  2 21:18:53 2024

(base) wannian07@wannian07-PC:~/Desktop$ cd …
(base) wannian07@wannian07-PC:~$ cd Unix-Network-Programming/
(base) wannian07@wannian07-PC:~/Unix-Network-Programming$ cd intro
测试的时候会出现如下错误connect error:Connection refused
第一种情况:没有xinetd.d,需要安装
sudo apt-get install xinetd
然后编辑daytime, wannian07@wannian07-PC# cd /etc/xinetd.d/
gedit daytime
将文件中的两个disable后面的yes改成no,保存退出
重启xinted.d
service xinetd restart
再次测试daytimetcpcli例子,
./daytimetcpcli 127.0.0.1
03 JUN 2024 18:45:28 CST
————:https://blog.csdn.net/terence1212/article/details/51803268

#include	"unp.h"int main(int argc, char **argv){union {short  s;char   c[sizeof(short)];} un;un.s = 0x0102;printf("%s: ", CPU_VENDOR_OS);if (sizeof(short) == 2) {if (un.c[0] == 1 && un.c[1] == 2)printf("big-endian\n");else if (un.c[0] == 2 && un.c[1] == 1)printf("little-endian\n");elseprintf("unknown\n");} elseprintf("sizeof(short) = %d\n", sizeof(short));exit(0);
}

//~/Unix-Network-Programming/intro/byteorder.c
wannian07@wannian07-PC:~/Unix-Network-Programming/intro$ make byteorder
gcc -I…/lib -g -O2 -D_REENTRANT -Wall -c -o byteorder.o byteorder.c
byteorder.c: In function ‘main’:
byteorder.c:21:28: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long unsigned int’ [-Wformat=]
printf(“sizeof(short) = %d\n”, sizeof(short));
^
gcc -I…/lib -g -O2 -D_REENTRANT -Wall -o byteorder byteorder.o …/libunp.a -lpthread
(base) wannian07@wannian07-PC:~/Unix-Network-Programming/intro$ ./byteorder
x86_64-unknown-linux-gnu: little-endian

1.2 一个简单的时间获取客户程序


#include	"unp.h"int
main(int argc, char **argv)
{int					sockfd, n;char				recvline[MAXLINE + 1];struct sockaddr_in	servaddr;if (argc != 2)err_quit("usage: a.out <IPaddress>");if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)err_sys("socket error");
//bzero把整个结构清零后,置地址族为AF_INET,  端口好为13bzero(&servaddr, sizeof(servaddr));servaddr.sin_family = AF_INET;servaddr.sin_port   = htons(13);	//htons()主机到网络短整数if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0)//inet_pton呈现形式到数值err_quit("inet_pton error for %s", argv[1]);
//IP地址为第一个命令行参数的值 argv[1]if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) < 0)err_sys("connect error");
//在头文件unp.h中,我们使用#define把SA定义为struct sockaddr,也就是通用套接字地址结构。while ( (n = read(sockfd, recvline, MAXLINE)) > 0) {recvline[n] = 0;	/* null terminate */if (fputs(recvline, stdout) == EOF)err_sys("fputs error");}if (n < 0)err_sys("read error");exit(0);
}

(base) wannian07@wannian07-PC:~/Unix-Network-Programming/intro$ 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
(base) wannian07@wannian07-PC:~/Unix-Network-Programming/intro$ sudo ./daytimetcpsrv &
[1] 13902
(base) wannian07@wannian07-PC:~/Unix-Network-Programming/intro$ ./daytimetcpcli 127.0.0.1
Sun Jun 2 21:18:53 2024
bzero不是一个ANSI C函数。它起源于早期的Berkeley网络编程代码。在整本书中使用它而不用ANSI C的memset函数,因为bzero(带2个参数)比memset(带3个参数)更好记忆。几乎所有支持套接字API的厂商都提供bzero,如果没有,那么可以使用unp.h头文件中提供的该函数的宏定义。
connect函数应用于一个TCP套接字时,将与由它的第二个参数指向的套接字地址结构指定的服务器建立一个TCP连接。该套接字地址结构的长度也必须作为该函数的第三个参数指定,对于网际套接字地址结构,我们总是使用C语言的sizeof操作符由编译器来计算这个长度。
socket一词译者认为译成“套接口”
首先,作为网络编程API之一的套接口(sockets,注意这种用法总是采用复数形式,如sockets API、sockets library等)跟XTI一样,是应用层到传输层或其他协议层的访问接口。
其次,具体使用的套接口是与Unix管道的某一端类似的东西,我们既可以往这个“口”写数据,也可以从这个“口”读数据。
最后,套接口函数使用套接口描述字(discriptor)访问具体的套接口,如果把套接口描述字的简称sockfd译成“套接字”倒比较合适。一个套接口可对应多个套接字,因为Unix的描述字既可以复制,也可以继承;反过来,一个套接字对应且只对应一个套接口。

UDP(User Datagram Protocol,用户数据报协议)
TCP(Transmission Control Protocol,传输控制协议)
1、计算机网络各层对等实体间交换的单位信息称为协议数据单元(protocol data unit,PDU)
分节(segment)就是对应于TCP传输层的PDU。
按照协议与服务之间的关系,除了最低层(物理层)外,每层的PDU通过由紧邻下层提供给本层的服务接口,作为下层的服务数据单元(service data unit,SDU)传递给下层,并由下层间接完成本层的PDU交换。
同一层内SDU作为PDU的净荷(payload)字段出现,因此可以说上层PDU由本层PDU(通过其SDU字段)承载。每层的PDU除用于承载紧邻上层的PDU(即承载数据)外,也用于承载本层协议内部通信所需的控制信息。
如果本层的PDU大小超过紧邻下层的最大SDU限制,那么本层还要事先把PDU划分成若干个合适的片段让下层分开载送,再在相反方向把这些片段重组成PDU。

2、应用层实体(如客户或服务器进程)间交换的PDU称为应用数据(application data),其中在TCP应用进程之
间交换的是没有长度限制的单个双向字节流,在UDP应用进程之间交换的是其长度不超过UDP发送缓冲区大小的
单个记录(record),在SCTP应用进程之间交换的是没有总长度限制的单个或多个双向记录流。
传输层实体(例如对应某个端口的传输层协议代码的一次运行)间交换的PDU称为消息(message),其中TCP的PDU特称为分节(segment)。消息或分节的长度是有限的。
在TCP传输层中,发送端TCP把来自应用进程的字节流数据(即由应用进程通过一次次输出操作写出到发送端TCP套接字中的数据)
按顺序经分割后封装在各个分节中传送给接收端TCP,其中每个分节所封装的数据既可能是发送端应用进程单次输出操作的结果,
也可能是连续数次输出操作的结果,而且每个分节所封装的单次输出操作的结果或者首尾两次输出操作的结果既可能是完整的,也可能是不完整的,具体取决于可在连接建立阶段由对端通告的最大分节大小(maximum segment size,MSS)以及外出接口的最大传输单元(maximum transmission unit,MTU)或外出路径的路径MTU(如果网络层具有路径MTU发现功能,如IPv6)。
分节除了用于承载应用数据外,也用于建立连接(SYN分节)、终止连接(FIN分节)、中止连接(RST
分节)、确认数据接收(ACK分节)、刷送待发数据(PSH分节)和携带紧急数据指针(URG分节),而且这些功
能(包括承载数据)可以灵活组合。
UDP传输层相当简单,发送端UDP就把来自应用进程的单个记录整个封装在UDP消息中传送给接收端UDP。 SCTP引入了称为块(chunk)的数据单元,SCTP消息就由一个公共首部加上一个或多个块构成:公共首部类似UDP消息的首部,仅仅给出源目的端口号和整个SCTP消息的校验和;
块则既可以承载数据(称为DATA块),也可以承载控制信息(计有SACK块、INIT块、INIT ACK块、COOKIE ECHO块、COOKIEACK块、SHUTDOWN块、SHUTDOWN ACK块、SHUTDOWN COMPLETE块、ABORT块、ERROR块、HEARTBEAT块和HEARTBEAT ACK块,总称为控制块)。
送端SCTP把来自应用进程的(一个或多个)记录流数据按照流内顺序和记录边界封装在各个DATA块中,并在DATA块首部记上各自的流ID。一个记录通常对应一个DATA块;
对于过长的记录,发送端SCTP既可以像UDP那样拒绝发送,也可以把它们拆分到多个DATA块中以便发送,接收端SCTP收取后把它们组合成单个记录上传。
作为传输层PDU的SCTP消息既可以只包含单个块(DATA块或控制块),也可以在接口MTU或路径MTU的限制下包含多个块(称为块的捆绑,控制块在前,DATA块在后),不过INIT块、INIT ACK块和SHUTDOWN COMPLETE块不能跟任何其他块捆绑。SCTP收发两端均独立处理捆绑在同一个消息中的各个块,鉴于此,我们可以直接把块作为传输层PDU看待,本书也往往这么使用。

3、网络层实体间交换的PDU称为IP数据报(IP datagram),其长度有限:
IPv4数据报最大65 535字节,IPv6数据报最大65 575字节。
发送端IP把来自传输层的消息(或TCP分节)整个封装在IP数据报中传送。
链路层实体间交换的PDU称为帧(frame),其长度取决于具体的接口。
IP数据报由IP首部和所承载的传输层数据(即网络层的SDU)构成。过长的IP数据报无法封装在单个帧中,需要先对其SDU进行分片(fragmentation),再把分成的各个片段(fragment)冠以新的IP首部封装到多个帧中。
在一个IP数据报从源端到目的端的传送过程中,分片操作既可能发生在源端,也可能发生在途中,而其逆操作即重组(reassembly)一般只发生在目的端;
SCTP为了传送过长的记录采取了类似的分片和重组措施。
TCP/IP协议族为提高效率会尽可能避免IP的分片/重组操作:TCP根据MSS和MTU限定每个分节的大小以及SCTP根据MTU分片/重组过长记录都是这个目的(SCTP的块捆绑则是为了在避免IP分片/重组操作的前提下提高块传输效率);
另外,IPv6禁止在途中的分片操作(基于其路径MTU发现功能),IPv4也尽量避免这种操作。
不论是否分片,都由IP作为链路层的SDU传入链路层,并由链路层封装在帧中的数据称为分组(packet,俗称包)。可见一个分组既可能是一个完整的IP数据报,也可能是某个IP数据报的SDU的一个片段被冠以新的IP首部后的结果。另外,本书中讨论的MSS是应用层(TCP)与传输层之间的接口属性,MTU则是网络层和链路层之间的接口属性。

1.3 协议无关性

#include	"unp.h"int
main(int argc, char **argv)
{int					sockfd, n;struct sockaddr_in6	servaddr;char				recvline[MAXLINE + 1];if (argc != 2)err_quit("usage: a.out <IPaddress>");if ( (sockfd = socket(AF_INET6, SOCK_STREAM, 0)) < 0)err_sys("socket error");bzero(&servaddr, sizeof(servaddr));servaddr.sin6_family = AF_INET6;servaddr.sin6_port   = htons(13);	/* daytime server */if (inet_pton(AF_INET6, argv[1], &servaddr.sin6_addr) <= 0)err_quit("inet_pton error for %s", argv[1]);if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) < 0)err_sys("connect error");while ( (n = read(sockfd, recvline, MAXLINE)) > 0) {recvline[n] = 0;	/* null terminate */if (fputs(recvline, stdout) == EOF)err_sys("fputs error");}if (n < 0)err_sys("read error");exit(0);
}

用户必须以点分十进制数格式给出服务器的IP地址(如适合于IPv4版本的206.168.112.219)。人们更习惯于用名字(如www.unpbook.com)来代替数字。

1.4 错误处理:包裹函数

既然发生错误时终止程序的运行是普遍的情况,我们可以通过定义包裹函数(wrapper function)来缩短程序。每个包裹函数完成实际的函数调用,检查返回值,并在发生错误时终止进程。我们约定包裹函数名是实际函数名的首字母大写形式。
sockfd = Socket(AF_INET, SOCK_STREAM, 0);
中,函数Socket是函数socket的包裹函数,只要你遇到一个首字母大写的函数名,它就是我们定义的某个包裹函数。它调用的实际函数的名字与包裹函数名相同,不过以对应的小写字母开头。

1.5 一个简单的时间获取服务器程序

#include	"unp.h"
#include	<time.h>int
main(int argc, char **argv)
{int					listenfd, connfd;struct sockaddr_in	servaddr;char				buff[MAXLINE];time_t				ticks;listenfd = Socket(AF_INET, SOCK_STREAM, 0);bzero(&servaddr, sizeof(servaddr));servaddr.sin_family      = AF_INET;servaddr.sin_addr.s_addr = htonl(INADDR_ANY);servaddr.sin_port        = htons(13);	/* daytime server */Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));Listen(listenfd, LISTENQ);for ( ; ; ) {connfd = Accept(listenfd, (SA *) NULL, NULL);ticks = time(NULL);snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));Write(connfd, buff, strlen(buff));Close(connfd);}
}

把套接字转换成监听套接字
调用listen函数把该套接字转换成一个监听套接字,这样来自客户的外来连接就可在该套接字上由内核接受。socket、bind和listen这3个调用步骤是任何TCP服务器准备所谓的监听描述符(listening descriptor,本例中为listenfd)的正常步骤。常值LISTENQ在我们的unp.h头文件中定义。它指定系统内核允许在这个监听描述符上排队的最大客户连接数。
接受客户连接,发送应答
通常情况下,服务器进程在accept调用中被置于休眠状态,等待某个客户连接的到达并被内核接受。TCP连接使用所谓的三路握手(three-way handshake)来建立连接。握手完毕时accept返回,其返回值是一个称为已连接描述符(connected descriptor)的新描述符(本例中为connfd)。该描述符用于与新近连接的那个客户通信。accept为每个连接到本服务器的客户返回一个新描述符。
当前时间和日期是由库函数time返回的,它实际上返回的是自Unix纪元即1970年1月1日0点0分0秒(国际标准时间)以来的秒数。下一个库函数ctime把该整数值转换成直观可读的时间格式,例如:
Mon May 26 20:58:40 2003
snprintf函数在这个字符串末尾添加一个回车符和一个回行符,随后write函数把结果字符串写给客户。调用sprintf无法检查目的缓冲区是否溢出。相反,snprintf要求其第二个参数指定目的缓冲区的大小,因此可确保该缓冲区不溢出。必须小心使用的函数还有gets、strcat和strcpy,通常应分别改为调用fgets、strncat和strncpy。更好的替代函数是后来才引入的strlcat和strlcpy,它们确保结果是正确终止的字符串。
注意。
与其客户程序一样,这一服务器程序也与IPv4协议相关。
本服务器一次只能处理一个客户。如果多个客户连接差不多同时到达,系统内核在某个最大数目的限制下把它们排入队列,然后每次返回一个给accept函数。本服务器只需调用time和ctime这两个库函数,运行速度很快。然而如果服务器需用较多时间(譬如说几秒钟或一分钟)服务每个客户,那么我们必须以某种方式重叠对各个客户的服务。所示的服务器称为迭代服务器(iterative server),因为对于每个客户它都迭代执行一次。同时能处理多个客户的并发服务器(concurrent server)有多种编写技术。最简单的技术是调用Unix的fork函数(4.7节),为每个客户创建一个子进程。其他技术包括使用线程代替fork(26.4节),或在服务器启动时预先fork一定数量的子进程(30.6节)。
如果从shell命令行启动本例这样的一个服务器,我们也许想要它运行很长时间,因为服务器往往在系统工作期间一直运行。这要求我们往服务器程序中添加代码,以便它能够作为一个Unix守护进程(daemon)—能在后台运行且不跟任何终端关联的进程—运行。

1.6 本书中客户/服务器程序示例索引表

1.7 OSI 模型

在这里插入图片描述

OSI模型的底下两层是随系统提供的设备驱动程序和网络硬件。通常情况下,除需知道数据链路的某些特性外(如将在2.11节论述的1500字节以太网的MTU大小)
网络层由IPv4和IPv6这两个协议处理。可以选择的传输层有TCP或UDP。图1-14中TCP与UDP之间留有间隙,表明网络应用绕过传输层直接使用IPv4或IPv6是可能的。这就是所谓的原始套接字(raw socket)。
OSI模型的顶上三层被合并成一层,称为应用层。这就是Web客户(浏览器)、Telnet客户、Web服务器、FTP服务器和其他我们在使用的网络应用所在的层。对于网际协议,OSI模型的顶上三层协议几乎没有区别。
套接字编程接口是从顶上三层(网际协议的应用层)进入传输层的接口。焦点是:如何使用套接字编写使用TCP或UDP的网络应用程序。已提到原始套接字,甚至可以彻底绕过IP层直接读写数据链路层的帧。
为什么套接字提供的是从OSI模型的顶上三层进入传输层的接口?这样设计有两个理由:
一、是顶上三层处理具体网络应用(如FTP、Telnet或HTTP)的所有细节,却对通信细节了解很少;底下四层对具体网络应用了解不多,却处理所有的通信细节:发送数据,等待确认,给无序到达的数据排序,计算并验证校验和,等等。
二、顶上三层通常构成所谓的用户进程(user process),底下四层却通常作为操作系统内核的一部分提供。Unix与其他现代操作系统都提供分隔用户进程与内核的机制。由此可见,第4层和第5层之间的接口是构建API的自然位置。

1.8 BSD 网络支持历史

1.9 测试用网络及主机

(1) netstat -i提供网络接口的信息。
(base) wannian07@wannian07-PC:~/Desktop$ netstat -ni
Kernel Interface table
Iface MTU RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg
lo 65536 12174 0 0 0 12174 0 0 0 LRU
wlp1s0 1500 37 0 308 0 157 0 0 0 BMU
(base) wannian07@wannian07-PC:~/Desktop$ netstat -nr
Kernel IP routing table
Destination Gateway Genmask Flags MSS Window irtt Iface

1.10 Unix 标准

POSIX(可移植操作系统接口)是Portable Operating System Interface的首字母缩写。它并不是单个标准,而是由电气与电子工程师学会(the Institute for Electrical and Electronics Engineers, Inc.)即IEEE开发的一系列标准。POSIX标准已被国际标准化组织即ISO和国际电工委员会(the International Electrotechnical Commission)即IEC采纳为国际标准(这两个组织合称为ISO/IEC)。
本书的焦点是单一Unix规范第3版,其中又以套接字API为主。只要可能,我们就使用标准函数

1.11 64 位体系结构

1.12 小结

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/357613.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【区块链】区块链架构设计:从原理到实践

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 区块链架构设计&#xff1a;从原理到实践引言一、区块链基础概念1.1 区块链定义…

k8s上使用ConfigMap 和 Secret

使用ConfigMap 和 Secret 实验目标&#xff1a; 学习如何使用 ConfigMap 和 Secret 来管理应用的配置。 实验步骤&#xff1a; 创建一个 ConfigMap 存储应用配置。创建一个 Secret 存储敏感信息&#xff08;如数据库密码&#xff09;。在 Pod 中挂载 ConfigMap 和 Secret&am…

荣耀社招 测试工程师 技术一面

面经哥只做互联网社招面试经历分享&#xff0c;关注我&#xff0c;每日推送精选面经&#xff0c;面试前&#xff0c;先找面经哥 1、自我介绍 2、具体介绍做过的项目&#xff0c;支撑的事什么业务 3、防火墙测试时、平时有写脚本或者使用第三方工具吗 4、对互联网的安全测试规…

浏览器插件利器-allWebPluginV2.0.0.14-bata版发布

allWebPlugin简介 allWebPlugin中间件是一款为用户提供安全、可靠、便捷的浏览器插件服务的中间件产品&#xff0c;致力于将浏览器插件重新应用到所有浏览器。它将现有ActiveX插件直接嵌入浏览器&#xff0c;实现插件加载、界面显示、接口调用、事件回调等。支持谷歌、火狐等浏…

DataStructure.时间和空间复杂度

时间和空间复杂度 【本节目标】1. 如何衡量一个算法的好坏2. 算法效率3. 时间复杂度3.1 时间复杂度的概念3.2 大O的渐进表示法3.3 推导大O阶方法3.4 常见时间复杂度计算举例3.4.1 示例13.4.2 示例23.4.3 示例33.4.4 示例43.4.5 示例53.4.6 示例63.4.7 示例7 4.空间复杂度4.1 示…

从零开始搭建一个酷炫的个人博客

效果图 一、搭建网站 git和hexo准备 注册GitHub本地安装Git绑定GitHub并提交文件安装npm和hexo&#xff0c;并绑定github上的仓库注意&#xff1a;上述教程都是Windows系统&#xff0c;Mac系统会更简单&#xff01; 域名准备 购买域名&#xff0c;买的是腾讯云域名&#xf…

神经网络实战1-Sequential

链接&#xff1a;https://pytorch.org/docs/1.8.1/generated/torch.nn.Sequential.html#torch.nn.Sequential 完成这样一个网络模型 第一步新建一个卷积层 self.conv1Conv2d(3,32,5)#第一步将33232输出为32通道&#xff0c;卷积核5*5 注意一下&#xff1a;输出通道数等于卷积…

JavaSE基础总结复习之面向对象の知识总结

目录 Java语言的基础特点 面向对象 类和对象 类 类的构造 一&#xff0c;发现类 二&#xff0c;发现类的共有属性&#xff08;成员变量&#xff09; 三&#xff0c;定义类的成员方法&#xff08;行为&#xff0c;动词&#xff09; 四&#xff0c;使用类创建对象 对象…

用TensorRT-LLM进行LLama的推理和部署

Deploy an AI Coding Assistant with NVIDIA TensorRT-LLM and NVIDIA Triton | NVIDIA Technical BlogQuick Start Guide — tensorrt_llm documentation (nvidia.github.io) 使用TensorRT-LLM的源码&#xff0c;来下载docker并在docker里编译TensorRT-LLM&#xff1b; 模型…

Eureka 服务注册与发现

目录 前言 注册中心 CAP 理论 常⻅的注册中心 CAP理论对比 Eureka 搭建 Eureka Server 引⼊ eureka-server 依赖 完善启动类 编写配置⽂件 启动服务 服务注册 引⼊ eureka-client 依赖 完善配置⽂件 启动服务 服务发现 引⼊依赖 完善配置⽂件 远程调⽤ 启动…

江协科技51单片机学习- p16 矩阵键盘

&#x1f680;write in front&#x1f680; &#x1f50e;大家好&#xff0c;我是黄桃罐头&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流 &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd;​…

web安全渗透测试十大常规项(一):web渗透测试之JAVA反序列化

渗透测试之PHP反序列化 1. Java反序列化1.1 Java安全-反序列化-原生序列化类函数1.1.1 原生序列化类函数:1.2 Java安全-SpringBoot框架-泄漏&CVE1. Java反序列化 1、序列化与反序列化 序列化:将内存中的对象压缩成字节流 反序列化:将字节流转化成内存中的对象2、为什么…

数据仓库和数据库有什么区别?

一、什么是数据仓库二、什么是数据库三、数据仓库和数据库有什么区别 一、什么是数据仓库 数据仓库&#xff08;Data Warehouse&#xff09;是一种专门用于存储和管理大量结构化数据的信息系统。它通过整合来自不同来源的数据&#xff0c;为企业提供统一、一致的数据视图&…

SuiNS发布子名及新命名标准,推动Web3身份结构的进步

SuiNS子名是Sui Name Service的强大扩展&#xff0c;最近与新命名标准一起发布。子名允许用户在一个主要的SuiNS名下创建额外的自定义身份&#xff0c;而无需额外费用。用户 gia 可以创建如 gaminggia 或 lendinggia 这样的子名&#xff0c;从而增强个人组织和支持群组与组织的…

通过Socket通信实现局域网下Amov无人机连接与数据传输

1.局域网下的通信 1.1 局域网 厂家提供的方式是通过Homer图数传工具(硬件)构建的amov局域网实现通信连接. 好处是通信距离足够长,支持150m;坏处是"局部",无法访问互联网. &#xff3b;&#xff29;&#xff2d;&#xff21;&#xff27;&#xff25;&#xff1a;…

AGV机器人的调度开发分析(1)- 内核中的路线规划

准备开始写一个系列&#xff0c;介绍下AGV机器人的调度的开发和应用。 按照openTCS的核心内容&#xff0c;国内多家广泛应用于AGV的调度。那么架构图如下&#xff1a; Kernel中有一个是Routing&#xff0c;这是路由规划模块&#xff0c;需要实现的细节功能包括如下&#xff1a…

SpringBoo+vue3+vite整合讯飞星火3.5通过webscoket实现聊天功能(前端代码)附带展示效果

访问地址&#xff1a; 天梦星服务平台 (tmxkj.top)https://tmxkj.top/#/site 后端文档&#xff1a; SpringBoovue3整合讯飞星火3.5通过webscoket实现聊天功能&#xff08;全网首发&#xff09;附带展示效果_springboot websocket vue3-CSDN博客https://blog.csdn.net/qq_53722…

2024 年值得推荐的 10 款 iPhone 数据恢复软件

iPhone 从来都不是一个简单的打电话电话。它就像一台微型电脑&#xff0c;让我们互相联系、拍照、拍视频、发邮件、看文档、看书。然而&#xff0c;随着它成为日常生活的必需品&#xff0c;我们总是容易因各种原因丢失数据&#xff0c;如删除、恢复出厂设置、iOS 错误、文件同步…

Django之云存储(二)

一、Django使用云存储 建立项目 django-admin startproject project_demo创建子应用 python manage.py startapp app_name修改配置文件,设置模板视图路径 settings.py TEMPLATES = [{BACKEND: django.template.backends.django.DjangoTemplates,DIRS: [os.path.join(BASE_DIR,…

【雷丰阳-谷粒商城 】【分布式高级篇-微服务架构篇】【13】压力压测JMeter-性能监控jvisualvm

持续学习&持续更新中… 守破离 【雷丰阳-谷粒商城 】【分布式高级篇-微服务架构篇】【13】压力压测JMeter-性能监控jvisualvm 压力测试概述性能指标 JMeter基本使用添加线程组添加 HTTP 请求添加监听器启动压测&查看分析结果JMeter Address Already in use 错误解决 性…