《TCP/IP网络编程》和《UNIX环境高级编程》读书笔记1

把unix环境高级编程通读完之后,对照着二刷tcp/ip网络编程,做些笔记整理一下,方便之后阅读。

tcp连接:可靠(一般不发生数据丢失),有序(先发先到),不存在边界 ----传送带模型

套接字约等于文件,fd文件描述符代表着文件编号,也是套接字的编号。每次系统分配的最小的未用的描述符

 套接字内部有缓冲(字节数组),有可能在好几次向套接字write后,等缓冲区填满后直接调用一次read,也可能分多次调用read,如果发生从缓冲区read的速度跟不上导致缓冲区填满,此时不会发生数据丢失(tcp连接),这种情况下write将阻塞。

udp连接:快速(相对来说容易丢包),无序,有边界,限制每次传输大小

三种类型的标准I/O缓冲

(1)全缓冲,填满缓冲区后才执行I/O操作,可以主动flush冲洗缓冲区

(2)行缓冲,遇到换行符执行I/O操作

(3)不带缓冲,不对字符进行缓冲存储,例如标准错误流stderr

服务端:socket创建套接字->bind绑定套接字与ip地址和端口号->listen宣告可接收请求了->accept受理请求

客户端:socket创建套接字->connect连接服务端地址

bind绑定服务器中具体的IP地址,建造了服务器要和外界通讯的大门,listen把大门打开,连接请求可以来排队了,accept受理请求后分配一个专门用来和该客户端通信的fd,这个fd和客户端调用socket函数分配的fd组成一个pair对,准确来说是套接字组成pair,就像书中开头讲到的插头与插座的概念,由此形成一条通路,进行网络通信。这两个fd的配对我理解是通过ip地址+端口唯一的识别出了他们的彼此。因为accept的时候有传出参数来表示请求的地址结构。

         

 IPV4  D类ip地址,前三字节表示网络id,第四字节表示主机id,先找网络地址,再找主机地址

大端序:高位字节存放低位地址

小端绪:高位字节存放高位地址

 tcp/ip网络字节序指定大端序

htonl、htons、ntohl、ntohs(主机字节序与网络字节序的转换)

inet_addr(inet_aton)、inet_ntoa(二进制地址格式与点分十进制字符表示的转换)

INADDR_ANY自动获取运行服务器端的计算机IP地址。

网络模型:物理层(光纤,电缆),数据链路层(网卡),网络层(IP、路由),传输层(TCP/UDP),应用层(HTTP等)

IP是面向消息的不可靠的协议。传输顺序与传输本身是不可靠的。

客户端只有在服务端listen后才能调用connect

 1 //tcp_server.cpp
 2 
 3 #include<iostream>
 4 #include<stdlib.h>
 5 #include<string.h>
 6 #include<unistd.h>
 7 #include<arpa/inet.h>
 8 #include<sys/socket.h>
 9 using namespace std;
10 
11 int main(int argc,char* argv[])
12 {
13     int serv_sock,clnt_sock;
14 
15     struct sockaddr_in serv_addr,clnt_addr;
16     socklen_t clnt_addr_size;
17     char message[] = "hello,world!";
18 
19     if(argc!=2){
20         cout<<"usage "<< argv[0] <<" port"<<endl;
21     }
22 
23     serv_sock = socket(AF_INET,SOCK_STREAM,0);
24     memset(&serv_addr,0,sizeof(serv_addr));
25     serv_addr.sin_family = AF_INET;
26     serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
27     serv_addr.sin_port = htons(atoi(argv[1]));
28     bind(serv_sock,(struct sockaddr*)&serv_addr,sizeof(serv_addr));
29     listen(serv_sock,5);
30     clnt_addr_size = sizeof(clnt_addr);
31     clnt_sock = accept(serv_sock,(struct sockaddr*)&clnt_addr,&clnt_addr_size);
32 
33     write(clnt_sock,message,sizeof(message));
34     close(clnt_sock);
35     close(serv_sock);
36     return 0;
37 }
View Code
 1 //tcp_client.cpp
 2 
 3 #include<iostream>
 4 #include<stdlib.h>
 5 #include<string.h>
 6 #include<unistd.h>
 7 #include<arpa/inet.h>
 8 #include<sys/socket.h>
 9 using namespace std;
10 
11 int main(int argc,char* argv[])
12 {
13     int clnt_sock;
14 
15     struct sockaddr_in serv_addr;
16     //socklen_t clnt_addr_size;
17     char message[30];
18 
19     if(argc!=3){
20         cout<<"usage "<< argv[0]<<" <address> <port>"<<endl;
21     }
22 
23     clnt_sock = socket(AF_INET,SOCK_STREAM,0);
24     memset(&serv_addr,0,sizeof(serv_addr));
25     serv_addr.sin_family = AF_INET;
26     serv_addr.sin_addr.s_addr = inet_addr(argv[1]);
27     serv_addr.sin_port = htons(atoi(argv[2]));
28     //bind(serv_sock,(struct sockaddr*)&serv_addr,sizeof(serv_addr));
29     //listen(serv_sock,5);
30     //clnt_addr_size = sizeof(clnt_addr);
31     connect(clnt_sock,(struct sockaddr*) &serv_addr,sizeof(serv_addr));
32     int idx = 0; int read_len = 0; int count = 0;
33     while(read_len = read(clnt_sock,&message[idx],1)) //每次读一个字节
34     {
35         if(read_len == -1)
36         {
37             cout<<"read error!"<<endl;
38         }
39         idx++;count++;
40     }
41     cout<<"message from server: "<<message<<endl;
42     cout<<"read function call count: "<<count<<endl;
43     close(clnt_sock);
44     return 0;
45 }
View Code
 1 //echo_server.cpp
 2 
 3 #include<iostream>
 4 #include<stdio.h>
 5 #include<stdlib.h>
 6 #include<string.h>
 7 #include<unistd.h>
 8 #include<arpa/inet.h>
 9 #include<sys/socket.h>
10 using namespace std;
11 
12 #define BUF_SIZE 1024
13 
14 int main(int argc, char* argv[])
15 {
16     int serv_sock, clnt_sock;
17 
18     struct sockaddr_in serv_addr, clnt_addr;
19     socklen_t clnt_addr_size;
20     char message[BUF_SIZE];
21 
22     if (argc != 2) {
23         cout << "usage " << argv[0] << " port" << endl;
24     }
25 
26     serv_sock = socket(AF_INET, SOCK_STREAM, 0);
27     memset(&serv_addr, 0, sizeof(serv_addr));
28     serv_addr.sin_family = AF_INET;
29     serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
30     serv_addr.sin_port = htons(atoi(argv[1]));
31     bind(serv_sock, (struct sockaddr*) & serv_addr, sizeof(serv_addr));
32     listen(serv_sock, 5);
33     clnt_addr_size = sizeof(clnt_addr);
34 
35     int str_len = 0;
36     for (int i = 0; i < 5; ++i)
37     {
38         clnt_sock = accept(serv_sock, (struct sockaddr*) & clnt_addr, &clnt_addr_size);
39         printf("connect client %d \n", i + 1);
40         while ((str_len = read(clnt_sock, message, BUF_SIZE)) != 0)
41             write(clnt_sock, message, str_len);
42         close(clnt_sock);
43     }
44     close(serv_sock);
45     return 0;
46 }
View Code
 1 //echo_client.cpp
 2 
 3 #include<iostream>
 4 #include<stdio.h>
 5 #include<stdlib.h>
 6 #include<string.h>
 7 #include<unistd.h>
 8 #include<arpa/inet.h>
 9 #include<sys/socket.h>
10 using namespace std;
11 
12 #define BUF_SIZE 1024
13 
14 int main(int argc, char* argv[])
15 {
16     int clnt_sock;
17     struct sockaddr_in serv_addr;
18     char message[BUF_SIZE];
19 
20     if (argc != 3) {
21         cout << "usage " << argv[0] << " <address> <port>" << endl;
22     }
23 
24     clnt_sock = socket(AF_INET, SOCK_STREAM, 0);
25     memset(&serv_addr, 0, sizeof(serv_addr));
26     serv_addr.sin_family = AF_INET;
27     serv_addr.sin_addr.s_addr = inet_addr(argv[1]);
28     serv_addr.sin_port = htons(atoi(argv[2]));
29 
30     connect(clnt_sock, (struct sockaddr*) & serv_addr, sizeof(serv_addr));
31     puts("connected...");
32 
33     int str_len,recv_len,recv_cnt;
34     while (1)
35     {
36         fputs("input q to quit: ", stdout);
37         fgets(message, BUF_SIZE, stdin);   //fgets会读入'\n'
38         if (message == "q\n" || message == "Q\n")
39             break;
40 
41         str_len = write(clnt_sock, message, strlen(message));
42         recv_len = 0;
43         while (recv_len < str_len)
44         {
45             recv_cnt = read(clnt_sock, &message[recv_len], BUF_SIZE - 1);
46             recv_len += recv_cnt;
47         }
48         message[BUF_SIZE] = '\0';
49         printf("message from server: %s", message);
50     }
51     close(clnt_sock);
52     return 0;
53 }
View Code

猜你喜欢

转载自www.cnblogs.com/iamyuxing/p/10912285.html
今日推荐