概述
首先是安装书上体统的源码根据它提供的readme进行安装,基本上没有问题。
1. 进入src目录
./configure
进行配置
2. 进入lib文件夹,编译基本函数
make
3. 进入libfree文件夹,编译基本函数库
make
4. 进入intro文件夹,编译源码
进行测试
wang@wang:~/Desktop/unpv13e/intro$ ./daytimetcpcli 127.0.0.1
Sun 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 sockaddr
if (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"
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);
}
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>
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), "%.24srn", 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 = %dn", 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 }
最后
以上就是贪玩猎豹为你收集整理的Unix Network Programming习题作业集的全部内容,希望文章能够帮你解决Unix Network Programming习题作业集所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复