套接字 socket
本地 IPC、网络通信
网络
计算机网络:有线或无线的链路连接多个设备(节点)进行数据通信或设备控制。
拓扑结构
- 星型网:局域网,
- 总线型:几个局域网连接
- 环型(令牌):城域网
- 复合型:综合
设备(节点)
- 计算机
- 交换机 switch、集线器 hub:连接计算机组成局域网
- 路由器 rounter:连接网络与网络
- 网关:过滤、拦截
- 中继器
- ...
介质
- 有线:双绞线(8)、电话线(4)、同轴电缆、光纤、电力
- 无线:移动网络、WIFI、蓝牙、红外、NFC、卫星...
MAC 物理地址
设备的序列号,是唯一的
以太网: 网线网络:C4-FF-99-D3-D2-22 WIFI:
IP 地址
IP 是逻辑编号,接入网络的设备,由 DHCP 自动的分配一个 IP 也可以手动绑定一个逻辑地址
MAC IP
C4-FF-99-D3-D2-22 10.162.238.35 C4-FF-99-D3-D2-22 10.162.238.36
IPv4: 32 2^32 42亿 IPv6: 128 2^128
SIM 序列号 手机号码
A类地址
范围:1.0.0.0 ~ 126.255.255.255(首字节0开头,二进制形式为0xxxxxxx)12
子网掩码:255.0.0.0(/8)13
用途:大型网络(如政府机构、跨国企业),每个网络支持约1677万台主机23
B类地址
范围:128.0.0.0 ~ 191.255.255.255(首字节10开头,二进制形式为10xxxxxx)12
子网掩码:255.255.0.0(/16)13
用途:中型网络(如大学、中型企业),每个网络支持约6.5万台主机
C类地址
范围:192.0.0.0 ~ 223.255.255.255(首字节110开头,二进制形式为110xxxxx)12
子网掩码:255.255.255.0(/24)13
用途:小型网络(如家庭、办公室),每个网络支持约254台主机
D类地址
范围:224.0.0.0 ~ 239.255.255.255(首字节1110开头,用于组播)12
用途:一对多通信(如视频会议、流媒体分发),无子网掩码
E类地址
范围:240.0.0.0 ~ 255.255.255.254(首字节1111开头,保留地址)12
用途:实验或未来使用,不可用于常规通信
126.255.255.255
11111111.00000000.00000000.00000000
126.0.0.0
126.2.25.55 255.0.0.0
126.0.0.0
端口号
一台机器中有多个程序, 每个程序还有还多进程或线程(浏览器每个标签页独立、迅雷)
操作系统中虚拟的接口,标记网络通信中进行数据收发的位置
一个程序可以占用多个端口
系统:2^16 65536个端口 前 1024 个端口保留,22 ssh, 80 www,
IP 计算机 端口 数据读取的位置:取件码
通信协议
通信双方预先约定的一套规则
ISO 国际标准化组织定义 OSI 开放系统互联参考模型
七层 意义:分层实现、一层之和相邻的层交互
- 应用层
- 表示层
- 会话层
- 传输层
- 网络层
- 数据链路层
- 物理层:电气接口相关的规范
主要贡献者:文森瑟夫、bill joy(vim、TCP/IP、Sun) TCP/IP 协议族
- 应用层:会话层、表示层、应用层 HTTP,HTTPS,SSH,SSL,POP,SMTP,自定义
- 传输层:TCP、UDP
- 网络层:IP
- 物理层:物理层、数据链路层
协议
- TCP/IP
*
- IPX
- NetBIOS
- apple
- xxx
参考资料
- 图解 TCP/IP 协议
- TCP/IP 详解(三卷)
知识点
- 三次握手
- 四次挥手
- 滑动窗口
- 掉包处理
- ...
socket 编程
套接字类型
- TCP 传输控制协议
- UDP 用户数据报协议
特征 | TCP | UDP |
---|---|---|
连接 | 是 | 否 |
有序 | 是 | 否 |
可靠 | 是 | 否 |
数据大小 | 不限 | 受限 |
开销 | 高 | 低 |
编程模型 | 客户服务器 | 对等 |
// server.c
// 服务端
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h>
#define NAME "tserver"
int main(int argc, char const *argv[])
{
// 删除
unlink(NAME);
// 1. 创建套接字:域,协议类型
int fd = socket(AF_UNIX, SOCK_STREAM, 0);
// 创建一个地址
// 本地通信
struct sockaddr_un addr;
addr.sun_family = AF_UNIX;
strcpy(addr.sun_path, NAME);
// 网络通信地址
// struct sockaddr_in addr2;
// addr2.sin_family = AF_INET;
// addr2.sin_port = 9000;
// 2. 套接字绑定地址
bind(fd, (struct sockaddr *)&addr, sizeof(addr));
// 3. 准备连接的队列
listen(fd, 4096);
printf("服务启动...\n");
while (1)
{
// 新套接字,连接客户端
int c_fd;
// 客户端的地址信息
struct sockaddr_un c_addr;
c_addr.sun_family = AF_UNIX;
int size = sizeof(c_addr);
// 接收连接
c_fd = accept(fd, (struct sockaddr *)&c_addr, &size);
// 读写
char buf[128];
memset(buf, '\0', 128);
read(c_fd, buf, 128);
printf("收到:%s\n", buf);
char msg[] = "bye TCP!";
write(c_fd, msg, sizeof(msg));
// 关闭客户端
close(c_fd);
}
return 0;
}
// client
// 客户端
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h>
#define NAME "tserver"
int main(int argc, char const *argv[])
{
// 1. 创建套接字
int fd = socket(AF_LOCAL, SOCK_STREAM, 0);
struct sockaddr_un addr;
addr.sun_family = AF_UNIX;
strcpy(addr.sun_path, NAME);
// 2. 连接
int r = connect(fd, (struct sockaddr *)&addr, sizeof(addr));
if (r == -1)
{
perror("客户端连接失败\n");
return EXIT_FAILURE;
}
// 3. 读写
printf("请输入:");
char buf[128];
fgets(buf, 128, stdin);
// 发送
write(fd, buf, 128);
// 接收
memset(buf, '\0', 128);
read(fd, buf, 128);
printf("收到:%s\n", buf);
// 4. 关闭连接
close(fd);
return 0;
}