OSI七层模型
- OSI:开放系统互联(Open System Interconnection)
具体7层 | 数据格式 | 功能与连接方式 | 典型设备 |
---|---|---|---|
应用层 Application | 数据Data | 网络服务与使用者应用程序间的一个接口 | 终端设备(PC、手机、平板等) |
表示层 Presentation | 数据Data | 数据表示、数据安全、数据压缩 | 终端设备(PC、手机、平板等) |
会话层 Session | 数据Data | 会话层连接到传输层的映射;会话连接的流量控制;数据传输;会话连接恢复与释放;会话连接管理、差错控制 | 终端设备(PC、手机、平板等) |
传输层 Transport | 数据组织成数据段Segment | 用一个寻址机制来标识一个特定的应用程序(端口号) | 终端设备(PC、手机、平板等) |
网络层 Network | 分割和重新组合数据包Packet | 基于网络层地址(IP地址)进行不同网络系统间的路径选择 | 路由器 |
数据链路层 Data Link | 将比特信息封装成数据帧Frame | 在物理层上建立、撤销、标识逻辑链接和链路复用 以及差错校验等功能。通过使用接收系统的硬件地址或物理地址来寻址 | 网桥、交换机 |
物理层Physical | 传输比特(bit)流 | 建立、维护和取消物理连接 | 光纤、同轴电缆、双绞线、网卡、中继器 |
- TCP/IP与OSI参考模型的对应关系
套接字(SOCKET)
套接字的类型
流式套接字(SOCK_STREAM):TCP
数据报式套接字(SOCK_DGRAM):UDP基于TCP(面向连接)的socket编程
服务器端程序:
- 1.创建套接字(socket)
- 2.将套接字绑定到一个本地地址和端口上(bind)
- 3.将套接字设为监听模式,准备接受客户请求(listen)
- 4.等待客户请求到来;当请求到来后,接受连接请求,返回一个新的对应于此连接的套接字(accept)
- 5.用返回的套接字和客户端进行通信(send/recv)
- 6.返回,等待另一客户请求
- 7.关闭套接字
客户端程序:
- 1.创建套接字(socket)
- 2.向服务器发出连接请求(connect)
- 3.和服务器端进行通信(send/recv)
- 4.关闭套接字
基于UDP(面向无连接)的socket编程
服务器端程序:
- 1.创建套接字(socket)
- 2.将套接字绑定到一个本地地址和端口上(bind)
- 3.等待接收数据(recvfrom)
- 4.关闭套接字
客户端程序:
- 1.创建套接字(socket)
- 2.向服务器发送数据(sendto)
- 3.关闭套接字
inet_addr()函数:可以将一个字符串作参数返回以点分十进制格式表示的IP地址
- inet_ntoa()函数:反之
- htonl()函数:转换u_long类型到网络字节序
- htons()函数:转换u_short类型到网络字节序
- bind函数中,TCP中经常用sockaddr_in代替sockaddr来方便填写信息
struct sockaddr_in
{
short sin_family;//地址族,对于IP地址,常为AF_INET
u_short sin_port;//端口号
struct in_addr sin_addr;//主机和IP地址
char sin_zero[8];//填充数,以使sockaddr_in结构和sockaddr结构的长度一样
};
- TCP代码实例
//服务器端
#include <iostream>
#include <WinSock2.h>
using namespace std;
#pragma comment(lib, "ws2_32.lib")
int main(int argc, char* argv[])
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(2, 2);
err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0)
{
cerr << "WSAStartup failed with error: " << err << endl;
return 1;
}
if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)
{
cerr << "Could not find a usable version of Winsock.dll" << endl;
WSACleanup();
return 1;
}
else
cout << "The Winsock 2.2 dll was found okay" << endl;
SOCKET sockSrv = socket(AF_INET, SOCK_STREAM, 0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(6000);
bind(sockSrv, (sockaddr*)&addrSrv, sizeof(addrSrv));
listen(sockSrv, 5);
SOCKADDR_IN addrClient;
int len = sizeof(SOCKADDR_IN);
while (1)
{
SOCKET sockCons = accept(sockSrv, (sockaddr*)&addrClient, &len);
char sendBuf[100];
sprintf_s(sendBuf, "Welcome %s to Flaming Chatting Room", inet_ntoa(addrClient.sin_addr));
send(sockCons, sendBuf, strlen(sendBuf) + 1, 0);
char recvBuf[100];
recv(sockCons, recvBuf, 100, 0);
cout << recvBuf << endl;
closesocket(sockCons);
}
WSACleanup();
return 0;
}
//客户端
#include <iostream>
#include <WinSock2.h>
using namespace std;
#pragma comment(lib, "ws2_32.lib")
int main(int argc, char* argv[])
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(2, 2);
err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0)
{
cerr << "WSAStartup failed with error: " << err << endl;
return 1;
}
if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)
{
cerr << "Could not find a usable version of Winsock.dll" << endl;
WSACleanup();
return 1;
}
else
cout << "The Winsock 2.2 dll was found okay" << endl;
SOCKET sockClient = socket(AF_INET, SOCK_STREAM, 0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(6000);
connect(sockClient, (sockaddr*)&addrSrv, sizeof(SOCKADDR));
char recvBuf[100];
recv(sockClient, recvBuf, 100, 0);
cout << recvBuf << endl;
send(sockClient, "this is zhangsan", strlen("this is zhangsan") + 1, 0);
closesocket(sockClient);
WSACleanup();
return 0;
}
- UDP代码实例
//服务器端
#include <iostream>
#include <WinSock2.h>
using namespace std;
#pragma comment(lib, "ws2_32.lib")
int main(int argc, char* argv[])
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(2, 2);
err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0)
{
cerr << "WSAStartup failed with error: " << err << endl;
return 1;
}
if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)
{
cerr << "Could not find a usable version of Winsock.dll" << endl;
WSACleanup();
return 1;
}
else
cout << "The Winsock 2.2 dll was found okay" << endl;
SOCKET sockSrv = socket(AF_INET, SOCK_DGRAM, 0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(6000);
bind(sockSrv, (sockaddr*)&addrSrv, sizeof(sockaddr));
SOCKADDR_IN addrClient;
int len = sizeof(SOCKADDR);
char recvBuf[100];
recvfrom(sockSrv, recvBuf, 100, 0, (sockaddr*)&addrClient, &len);
cout << recvBuf << endl;
closesocket(sockSrv);
WSACleanup();
return 0;
}
//客户端
#include <iostream>
#include <WinSock2.h>
using namespace std;
#pragma comment(lib, "ws2_32.lib")
int main(int argc, char* argv[])
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(2, 2);
err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0)
{
cerr << "WSAStartup failed with error: " << err << endl;
return 1;
}
if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)
{
cerr << "Could not find a usable version of Winsock.dll" << endl;
WSACleanup();
return 1;
}
else
cout << "The Winsock 2.2 dll was found okay" << endl;
SOCKET sockClient = socket(AF_INET, SOCK_DGRAM, 0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(6000);
sendto(sockClient, "Hello", strlen("Hello") + 1, 0, (sockaddr*)&addrSrv, sizeof(sockaddr));
closesocket(sockClient);
WSACleanup();
return 0;
}