Unix Network Programming习题作业集

来源:互联网 发布:期货决策软件 编辑:程序博客网 时间:2024/06/07 09:08

首先是安装书上体统的源码根据它提供的readme进行安装,基本上没有问题。

1. 进入src目录

./configure

进行配置

2. 进入lib文件夹,编译基本函数

make

3. 进入libfree文件夹,编译基本函数库

make

4. 进入intro文件夹,编译源码

进行测试

wang@wang:~/Desktop/unpv13e/intro$ ./daytimetcpcli 127.0.0.1Sun Aug 20 09:24:41 2017
表示已经成功,记得开启./daytimecpcsrv服务。


第一部分 Introduction and TCP/IP

第一章 Introduction

1. Deciding that the client always initiates(发起) requests tends to simplify the protocol as well as the programs themselves.

2. The client application and the server application may be thought of as communicating via a network protocol, but actually multiple layers of network protocols are typically involved.

3. 举例

The client establishes a TCP connection with a server and the server simply sends back the current time and date in human-readable format.

4. The socket function create an Internet (AF_INET) stream (SOCK_STREAM) socket, which is fancy name for a TCP socket.

5. We fill in an Internet socket address structure (a sockaddr_in structure named servaddr) with the server's IP address and port number.

6. htons to cenvert the binary port number.

7. The connect function, when applied to the TCP socket, establishes a TCP connection with the server specified by the socket address structure pointed to by the second argument.

完整的客户端程序如下

#include "unp.h"int main(int argc, char **argv) {int sockfd, n;struct sockaddr_in servaddr;char recvline[MAXLINE+1];if (argc != 2) {err_quit("usage: argv[0] <IPaddress>");}if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)err_sys("socket error");bzero(&servaddr, sizeof(servaddr));servaddr.sin_family = AF_INET;servaddr.sin_port = htons(13);if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0)err_quit("inet_pton error for %s", argv[1]);// #define SA struct sockaddrif (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) < 0) err_sys("connect error");while ((n = read(sockfd, recvline, MAXLINE)) > 0) {recvline[n] = 0;if (fputs(recvline, stdout) == EOF)err_sys("fputs error");}if (n < 0)err_sys("read error");exit(0);}
建立socket, 创建sockaddr_in结构体,绑定连接,读取数据写入到终端,结束完成。

8. IPv6结构

#include"unp.h"intmain(int argc, char **argv){intsockfd, n;struct sockaddr_in6servaddr;charrecvline[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);}

9. 使用包裹函数简化错误处理

int Socket(int family, int type, int protocol) {    int n;    if ((n = socket(family, type, protocol)) < 0)err_sys("socket error");    return n;}
10. 错误处理

When an error occurs in a Unix function, the global variable errno is set to a positive value indicating the type of error and the function normally returns -1.

Our err_sys function looks at the value of errno and prints the corresponding error message string.

11. 创建一个服务器程序步骤

1. create a TCP socket

2. Bind server's well-known port to socket

3. Convert socket to listening socket

12. Normally, the server process is put to sleep in the call to accept, waiting for a client connection to arrive and be accepted.

A TCP connection uses what is called a three-way handshake to establish a connection. When this handshake completes, accept returns, and the return vlaue from the function is a new descriptor (connfd) that is called the connected descriptor.

#include"unp.h"#include<time.h>intmain(int argc, char **argv){intlistenfd, connfd;struct sockaddr_inservaddr;charbuff[MAXLINE];time_tticks;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);    }}
The server closes its connection with the client by calling close.

This initiates the normal TCP connection termination sequence: a FIN is sent in each direction and each FIN is acknowledged by the other end.

13. 常用unit命令

wang@wang:~$ netstat -ni
Kernel Interface table
Iface   MTU Met   RX-OK RX-ERR RX-DRP RX-OVR    TX-OK TX-ERR TX-DRP TX-OVR Flg
eth0       1500 0     62894      0      0 0         56402      0      0      0 BMRU
lo        65536 0    133888      0      0 0        133888      0      0      0 LRU

netstat -nr

ifconfig eth0

ping -b 206.168.112.127

习题

1.1 尝试常用的命令

1.2 编译书上的示例

1.3 连接错误

1.4 read的次数

 22     int count = 0; 23     while ((n = read(sockfd, recvline, MAXLINE)) > 0) { 24         if (n > 0) count++; 25         recvline[n] = 0; 26         if (fputs(recvline, stdout) == EOF) 27             err_sys("fputs error"); 28     } 29     printf("count = %d\n", count);
wang@wang:~/Desktop/unpv13e/intro$ ./sample 127.0.0.1
Sun Aug 20 11:37:16 2017
count = 1

1.5 单个字符写出

 28         // Write(connfd, buff, strlen(buff)); 29         int i; 30         for (i = 0; i < strlen(buff); i++) { 31             Write(connfd, &buff[i], 1); 32         }





原创粉丝点击