板凳-------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.mzph.cn/web/34962.shtml

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

相关文章

js+php 上传文件到服务器

https://andi.cn/page/621473.html

喂饭级AI神器!免代码一键绘制图表,文本数据秒变惊艳视觉盛宴!

由于目前的AI生成图表工具存在以下几个方面的问题&#xff1a; 大多AI图表平台是纯英文&#xff0c;对国内用户来说不够友好&#xff1b;部分平台在生成图表前仍需选择图表类型、配置项&#xff0c;操作繁琐&#xff1b;他们仍需一份规整的数据表格&#xff0c;需要人为对数据…

“论模型驱动架构设计方法及其应用”写作框架,软考高级,系统架构设计师

论文真题 模型驱动架构设计是一种用于应用系统开发的软件设计方法&#xff0c;以模型构造、模型转换和精化为核心&#xff0c;提供了一套软件设计的指导规范。在模型驱动架构环境下&#xff0c;通过创建出机器可读和高度抽象的模型实现对不同问题域的描述&#xff0c;这些模型…

【Win】双系统新体验:Hyper-V上macOS安装攻略

在虚拟化的世界里&#xff0c;Hyper-V是探索不同操作系统的一扇大门。尽管macOS并不是Hyper-V官方支持的来宾操作系统&#xff0c;但这并未阻挡技术探索者的脚步。他们通过不懈努力&#xff0c;开辟出了一条条通往macOS的非官方路径。这些路径或许曲折&#xff0c;却为那些渴望…

Ubuntu挂载window的网络共享文件夹爱

1.进入win10创建一个用户smb密码也是smb 2.右键进入文件夹共享 3.进入Ubuntu安装支持cifs-utils sudo apt update sudo apt install cifs-utils 4.sudo mkdir /mnt/shared 5.挂载&#xff1a; sudo mount -t cifs -o usernamesm bpasswordsmb //172.16.11.37(windowsIP)/s…

controller不同的后端路径对应vue前端传递数据发送请求的方式

目录 案例一&#xff1a; 为什么使用post发送请求&#xff0c;参数依旧会被拼接带url上呢&#xff1f;这应该就是param 与data传参的区别。即param传参数参数会被拼接到url后&#xff0c;data会以请求体传递 补充&#xff1a;后端controller 参数上如果没写任何注解&#xff0c…

JVM专题十二:JVM 中的收集器二

上一篇JVM专题十一&#xff1a;JVM 中的收集器一咱们介绍了垃圾收集器的分类&#xff0c;已经主流的分代垃圾收集器重点看了CMS与三色标记算法&#xff0c;本篇咱们继续来看意G1、ZGC等。 G1收集器 G1&#xff08;Garbage-First Garbage Collector&#xff09;是一种服务器端的…

flask的基本使用1

【 一 】Flask介绍 python 界的web框架 -Django&#xff1a;大而全&#xff0c;使用率较高 &#xff1a;https://github.com/django/django -FastAPI&#xff1a;新项目选择使用它&#xff1a;https://github.com/tiangolo/fastapi -flask&#xff1a;公司一些小项目使用它&a…

如何提高软件APP质量的测试类型

如今&#xff0c;由于市场竞争非常激烈&#xff0c;移动应用质量至关重要。我们需要关注用户体验以及应用的性能。如果应用包含错误&#xff0c;应用评级就会下降&#xff0c;应用下载量也会下降。如果我们能使我们的应用没有错误&#xff0c;那么应用获得人气的机会就会增加。…

通过颜色传感器控制机械臂抓物体

目录 1 绪论 2整体设计方案 2.1 系统的介绍 2.2 抓取模块 2.2.1 机械臂的定义 2.2.2 机械臂的分类 2.2.3 机械臂的选用 2.3 颜色识别模块 2.3.1 颜色传感器识别原理 2.3.2 TCS3200简介 2.4 整体控制方案 3 颜色识别抓取系统的硬件设计 3.1 单片机选型及参数 3.2 系…

win11系统重装?正版系统Windows11安装重启!保姆级重装系统攻略!

随着科技的不断发展&#xff0c;Windows 11系统已经逐渐成为了众多电脑用户的新选择。然而&#xff0c;当当电脑出现严重故障、受到病毒攻击、软件冲突、系统升级失败、硬件更换或升级、系统性能下降或个性化需求等情况时&#xff0c;重装系统可能是一个有效的解决方案。本文将…

构建网络图 (JavaScript)

前序&#xff1a;在工作中难免有一些千奇百怪的需求&#xff0c;如果你遇到构建网络图&#xff0c;或者学习应对未来&#xff0c;请看这边文章&#xff0c;本文以代码为主。 网络图是数据可视化中实用而有效的工具&#xff0c;特别适用于说明复杂系统内的关系和连接。这些图表…

【十六】【QT开发应用】Menu菜单,contextMenuEvent,setContextMenuPolicy,addAction

在 Qt 框架中&#xff0c;QMenu 类用于创建和管理菜单。菜单是用户界面的一部分&#xff0c;可以包含多个选项或动作&#xff0c;用户可以选择这些选项来执行特定的功能。菜单通常显示在菜单栏、上下文菜单&#xff08;右键菜单&#xff09;或工具栏中。 基本用法 创建菜单对象…

深入解读一下 `com.google.android.material.appbar.CollapsingToolbarLayout`

简介 在现代 Android 应用中&#xff0c;提供流畅且美观的用户体验是非常重要的。CollapsingToolbarLayout 是 AndroidX库中 Material Components 的一部分&#xff0c;它提供了一种易于实现的可折叠工具栏效果&#xff0c;常用于提供视觉吸引力的标题栏和动画效果。 本文将详…

项目1111

中文显示姓名列和手机号 SELECT contact_name AS 姓名, contact_phone AS 手机号 FROM 2_公司id; 使用explain测试给出的查询语句&#xff0c;显示走了索引查询 EXPLAIN SELECT * FROM 7_订单数量 WHERE countid LIKE e%; 统计用户订单信息&#xff0c;查询所有用户的下单数量…

Prometheus中添加基本身份验证功能

在Prometheus中添加基本身份验证功能&#xff0c;可以按照以下步骤进行&#xff1a; 一、生成哈希密码 首先&#xff0c;需要安装bcrypt工具&#xff0c;用于生成哈希密码。这可以通过Python的bcrypt库来完成。如果未安装&#xff0c;可以使用pip进行安装。 创建一个Python脚…

Android性能优化——卡顿优化

文章目录 一、从XML到屏幕上的展示造成跳帧的因素有那些发现问题定位问题定位代码 一、从XML到屏幕上的展示 数据加载阶段 数据控制阶段 数据展示阶段 xml —> view onCreat —> 解析layout.xml resume —> view —> wms ViewRootImpl UI 绘制流程 &#xff1a;测…

计算机网络之数据通信原理

1.通信系统的基本组成 信源&#xff1a;信息的发出者&#xff1b; 信宿&#xff1a;信息的接收者&#xff1b; 载体&#xff1a;信息的传送通道&#xff1b; 变换器&#xff1a;将信息变换成载体上可传输的信号&#xff1b; 反变换器&#xff1a;将载体上传输的信号变换成信…

SpringBoot集成Druid数据库连接池并配置可视化界面和监控慢SQL

pom.xml <!-- Druid 数据库连接池 --><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.2.23</version></dependency>application.yml spring:jackson:date-…

明星周边物品交易购物系统

摘 要 随着明星文化的兴起和粉丝经济的蓬勃发展&#xff0c;明星周边产品的市场需求日益增长。明星周边物品包括各种与明星相关的商品&#xff0c;如T恤、海报、手办、签名照等&#xff0c;它们成为粉丝们表达对明星喜爱和支持的方式之一。通过“星光璀璨”来形象化地表达明星…