TCP/IP: Echo Server/Client
To setup an application, two models:
- Client/Server model (Web)
一个结点或是server,或是client - Peer-to-peer (P2P) model (PPLive)
一个server没了,一个client可以变server补充
Client/server model
- Clent端 主动请求服务!
- Server 同时服务于很多client
Client
- client是一个过程,而不是说是具体的一台计算机/机器
- client特别主动主动 (就像学生主动找老师)
- client完成后才关闭服务
Before communication, client requires:
- IP address
- Post number
多试错…注意IANA已经分配的
Client’s function:
考试会考,不同角度回答都行,下面也是正确的答案
- Translate the user’s request into the desired protocol.
- Send the request to the server.
- Wait for the server’s response.
- Translate the response into “human readable” results.
- Present the results to the user.
Server
- Server是一个过程,而不是说是具体的一台计算机/机器
- Server一旦开启,持续持续地运行
- Server被动地去接受request (passively)
- Server各方面都比Client复杂
两种类型的servers
- 迭代服务器 (Iterative)
一个时间段,只能处理一个(老师指导) - 并发服务器 (Concurrent)
可处理多个 (老师上课)
Server’s function:
- Listen for a client’s query
- Process the query
- Return the results back to the client
一个典型的client/server交互:(考试稍微漏两条没答-没事)
- The user runs client software to create a query.
- The client connects to the server.
- The client sends the query to the server.
- The server accept the query.
- The server computes the result of the query.
- The server sends the results to the client.
- The client presents the results to the user.
TCP 客户端和服务端交互的流程图
这个必须要有印象,考试可能空几个出来让你填,特别是右边绿色部分。
比喻成打电话的过程
1. 电话的地址定义:
struct sockaddr {
unsigned short sa family; // address family,
AF xxxchar sa data[14]; // 14 bytes of protocol address
};
struct sockaddr_in {
shortintsin family;// Address family
unsignedintsin _port; // Port numbershort
structin addrsin addr; /* Internet address */
unsignedsin zero[8];/* Same size as struct sockaddr */
};
struct in_addr {
unsigned long s_addr;
};
sockaddr 和 sockaddr_in 结构体的区别:
sockaddr 是一个通用的地址结构体,用于传递和储存地址
sockaddr_in 是用于表示IPv4地址和端口号的结构体
Address family:
- AF_INET: IPv4
- AF_INET6: IPv6
Port number
16-bit TCP or UDP port number
sin_addr
32-bit IPv4地址
sin_zero
无实际意义。填充字段,以保持结构体 sockaddr_in 与 sockaddr 的大小一致。
2. 准备电话:
#include <sys/types.h>
#include <sys/socket.h>
int socket(int family, int type, int protocol)
- return nonnegative descriptor, if OK,
- -1, if error
mySock = socket(family, type, protocol)
int serv_sock;
int clnt_sock;
struct sockaddr_in serv_addr;
struct sockaddr_in clnt_addr;
socklen_t clnt_addr_size;
char message[] = "Hello MUST!";
if(argc != 2){
print("usage : %s <port>\n", argv[0]);
exit(1);
}
serv_sock = socket(PF_INET, SOCK_STREAM, 0);
if(serv_sock == -1)
error_handling("socket() error");
3.用电话拨打号码
Bind: 给socket分配local IP地址和端口
#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr* myaddr, unsigned int addrlen)
- returns 0 if OK,
- -1 if error
//bind addr/ip to socket
if (bind(serv_sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == -1)
{
printf("bind error\n");
exit(0);
}
Overall:
- Create a new socket;
- Print the fd of the socket
- Bind your local address/port to the socket.
p.s
转网络字节序发送!
计算机存储是高节序还是低节序(考试考)?
- 高节序(Big Endian): 高存低 | 0x12345678 字节的存储顺序为 12 34 56 78
- 低节序(Little Endian):低存低 | 0x12345678 字节的存储顺序为 78 56 34 12
x86 和 x86-64 处理器:低节序
ARM 处理器:低节序/高节序,具体取决于处理器配置
PowerPC 处理器:高节序
以下是一些常见的文件描述符值的含义:
0: 标准输入(stdin)
1: 标准输出(stdout)
2: 标准错误输出(stderr)
其他文件描述符的值从 3 开始递增。
(补9.22课)