1.进程是人在系统中的代表,只要进程拿到数据就相当于人拿到数据
2.数据传输到主机不是目的而是手段。数据到达主机内部,再交给主机内的进程才是目的
3.进程(内存)--> 网卡-->网络
4.网络通信的本质是两个不同主机的进程进行数据交互
或者说:网络通信的本质是进程间通信
5.端口号是传输层的内容,大小为2字节,用来标识一个进程的唯一性
6.端口号 VS pid
(1)不是所有进程都要进行网络通信,即进程一定有pid,但是不一定有端口号
(2)从技术手段上来说,用pid计数是可行的,但是pid是一个系统概念,若pid变化了,网络也要跟着变化,两者是解耦的
7.IP地址表示全网唯一的主机
port表示该主机内唯一的网络进程
IP+port=全网内唯一的一个进程=socket
----->网络通信的本质是全网内唯二的两个进程间通信
8.一个端口号只能对应一个进程,但是一个进程可以对应多个端口号
9.端口号的范围:0~65535,其中0~1023是知名端口号,作为一些公共熟知的端口使用;1024~65535是由操作系统动态分配的端口号
10.传输层的典型代表:TCP协议,UDP协议
(1)TCP:有连接,可靠传输,面向字节流
(2)UDP:无连接,不可靠传输,面向数据报
11.网络字节序:凡是到达网络的数据必须是以大端形式存储的
12.socket编程的接口(已使用UDP协议为例)
<1>套接字类型:
- 流式Socket(SOCK_STREAM):可靠双向字节流(TCP)
- 数据报Socket(SOCK_DGRAM):无连接数据包(UDP)
- 原始Socket(SOCK_RAW):直接访问IP层
地址结构
struct sockaddr_in {
sa_family_t sin_family; // AF_INET/AF_INET6
in_port_t sin_port; // 16位端口号(网络字节序)
struct in_addr sin_addr; // IPv4地址
};
<2>int socket(int domain, int type, int protocol);
函数原型
#include <sys/types.h>
#include <sys/socket.h>
int socket(int domain, int type, int protocol);
作用:创建网络通信端点的核心函数,属于套接字API的基础部分
参数介绍
- domain(地址族)
AF_INET
:IPv4协议(常设置为这种形式)AF_INET6
:IPv6协议AF_LOCAL
(或AF_UNIX
):本地进程间通信(IPC)AF_PACKET
:底层数据包访问
- type(套接字类型)
SOCK_STREAM
:面向连接的流式套接字(TCP)SOCK_DGRAM
:无连接的数据报套接字(UDP)SOCK_RAW
:原始套接字(直接访问网络层)SOCK_SEQPACKET
:可靠的数据包序列传输
- protocol(协议类型)
- 通常设为0,系统会自动选择指定domain和type下的默认协议
- 特殊需求时可指定具体协议号(如
IPPROTO_TCP
)
返回值:
- 成功:返回新的套接字描述符(非负整数)
- 失败:返回-1,并设置
errno
表示错误类型
<3>int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
函数原型
#include <sys/types.h>
#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
作用:bind()
函数是网络编程中用于将套接字与特定地址和端口绑定的关键函数,通常用于服务端程序
参数介绍
- sockfd
- 通过
socket()
函数创建的套接字描述符
- 通过
- addr
- 指向
sockaddr
结构体的指针,包含要绑定的地址和端口信息 - 实际使用时通常转换为特定协议的结构体(如
sockaddr_in
)
- 指向
- addrlen
- 地址结构体的长度(字节数)
返回值:
- 成功:返回0
- 失败:返回-1,并设置
errno
表示错误类型
<4>ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen);
函数原型
#include <sys/types.h>
#include <sys/socket.h>
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen);
作用:recvfrom()
函数是网络编程中用于从套接字接收数据的核心函数,特别适用于无连接协议(如UDP)或需要获取发送方地址信息的场景
参数介绍
- sockfd
- 套接字描述符(需为已绑定的UDP套接字或面向无连接的套接字)。
- buf
- 指向接收缓冲区的指针,用于存储接收到的数据。
- len
- 缓冲区长度(字节数)。
- flags
- 控制接收行为的标志位(常用值):
0
:默认阻塞接收。MSG_DONTWAIT
:非阻塞模式。MSG_PEEK
:查看数据但不移除缓冲区。MSG_WAITALL
:等待接收完整数据(不适用于UDP)。
- 控制接收行为的标志位(常用值):
- src_addr
- 输出参数,指向
sockaddr
结构体的指针,用于存储发送方地址信息。 - 若无需获取发送方地址,可设为
NULL
。
- 输出参数,指向
- addrlen
- 输入/输出参数:
- 输入时:指定
src_addr
结构体的长度。 - 输出时:返回实际填充的地址长度。
- 输入时:指定
- 若无需获取发送方地址,可设为
NULL
。
- 输入/输出参数:
返回值
- 成功:返回实际接收的字节数(可能小于
len
)。 - 错误:返回
-1
,并设置errno
表示错误类型(如EAGAIN
非阻塞模式下无数据可读)。 - 对端关闭:返回
0
(仅适用于面向连接的套接字,UDP中不适用)。
<5>ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
const struct sockaddr *dest_addr, socklen_t addrlen);
函数原型
#include <sys/types.h>
#include <sys/socket.h>
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
const struct sockaddr *dest_addr, socklen_t addrlen);
作用:sendto()
函数是网络编程中用于通过无连接套接字(如UDP)发送数据的核心函数。它允许指定目标地址,适用于需要向特定接收方发送数据报的场景。
参数介绍
- sockfd
- 套接字描述符(需为已绑定的UDP套接字或面向无连接的套接字)。
- buf
- 指向待发送数据的缓冲区指针。
- len
- 要发送的数据长度(字节数)。
- flags
- 控制发送行为的标志位(常用值):
0
:默认阻塞发送。MSG_DONTWAIT
:非阻塞模式。MSG_CONFIRM
:通知协议层链路层缓存有效(仅部分系统支持)。MSG_MORE
:后续还有数据要发送(如TCP的Nagle算法优化)。
- 控制发送行为的标志位(常用值):
- dest_addr
- 指向
sockaddr
结构体的指针,指定目标地址和端口。 - 若套接字已连接(通过
connect()
),可设为NULL
。
- 指向
- addrlen
- 目标地址结构体的长度(字节数)。
返回值
- 成功:返回实际发送的字节数(可能小于
len
)。 - 错误:返回
-1
,并设置errno
表示错误类型(如EAGAIN
非阻塞模式下无法立即发送)。