网络编程其实就是要在遵循网络协议的条件下进行编程从而达到计算机之间可以通信。
在这之前先了解一些网络基础:
https://blog.csdn.net/LSFAN0213/article/details/81537821
了解什么是网络编程之前,我们要先了解一些预备知识
IP地址:
IP协议有两个版本:IPV4 和 IPV6,但是我们一般使用的是IPV4版本
IP地址是什么?
IP地址是IP协议中,用来标识网络中不同主机的地址。对于IPV4来说,IP地址是一个4字节,32位的整数。我们通常使用“点分十进制”的字符串来表示IP地址,例如:192.168.0.1;用点分割的每一个数字表示一个字节,范围是0 ~ 255。
在IP数据包头部,有2个IP地址,分别叫做源IP地址和目的IP地址,有了这两个IP地址,我们才满足了发送数据的基本条件。
但是,只有IP地址也是不够的,想象一下我们发QQ消息,有了IP地址能够把消息发送到对方的机器上,但是我们还需要有一个其他的标识来区分出,这个数据要给哪一个程序进行解析。
这里,就引出了端口号:
端口号(port)是是传输层协议的内容。
端口号是一个2字节16位的整数
端口号用来标识一个进程,告诉操作系统,当前这个数据要交给哪一个进程来处理
IP地址+端口号能够标识网络上某一台主机的某一个进程
一个端口号只能被一个进程占用
我们知道每个进程都有一个进程ID,哪这个端口号和进程ID有什么分别?
其实很简单,端口号一次只能被一个进程绑定,而一个进程却可以同时绑定多个端口号
和IP地址一样,我们的端口号也分为源端口号和目的端口号,就是在描述“数据是谁发的,要发给谁”
认识TCP协议和UDP协议
TCP(Transmission Control Protocol 传输控制协议):
1.它是传输层的一个协议
2.它是一个面向连接的协议(我们可以理解为打电话,只有电话通了,两个人才可以说话)
3.它是一种可靠传输
4.面向字节流(可以理解为像水一样传输数据)
UDP(User Datagram Protocol 用户数据报协议):
1.它是传输层的一个协议
2.它是一个无连接的协议(我们可以理解为发短信,不需要建立连接就可以发送数据)
3.它是一种不可靠传输(因为它面向无连接,所以必然是一种不可靠的传输)
4.面向数据报(可以理解为像冰块一样一块一块发送数据)
我们已经知道,内存中的很多字节数据相当于内存地址有大小端之分,网络数据流同样有大小端之分,那么如何定义网络数据流的地址呢?
其实,因为每台主机由不同的厂商制作出来,大小端难免会不一致,所以,为了避免这个问题,TCP/IP协议规定:网络数据流采用的是大端字节序,即低地址高字节。所以,这样一来,不管主机是大端还是小端,都会按照这个TCP/IP规定的网络字节序来发送/接收数据
下来我们主要了解socket编程接口
socket常见的API:
int socket(int domain,int type,int protocol);
这是创建socket套接字的接口;函数中:
domain:是一个文件描述符,后序操作都是通过这个文件描述来运行
type:这个参数来说明这是一个什么样类型的socket
protocol:这个参数是来描述具体的协议
int bind(int socket,const struct sockaddr *address,socklen_t address_in)
这是绑定端口的函数
struct sockaddr *address :这个参数是需要绑定套接字的地址
socklen_t address_in: 地址的长度
下面函数的参数都差不多,就不具体解释了
int listen(int socket,int backlog)
这是监听socket的函数
这里的backlog要说明一下:它是最大可并行的链接数
int accept(int socket,struct sockaddr *address,socklen_t *address_len);
接收函数
int connect(int sockfd,const struct sockaddr *addr,socklen_t addrlen);
建立连接函数
在这些函数里,多次出现了sockaddr 这个结构体,我们来了解下scokaddr这个结构体:
我们通常使用的是第二种struct sockaddr_in
sockaddr结构:
struct sockaddr{
__SOCKADDR_COMMON(sa_);
char sa_data[14];
};
sockddr_in结构
struct sockaddr_in
{
__SOCKADDR_COMMON(sin_);
int_port_t sin_port;
struct in_addr sin_addr;
unsigned char sin_zero[sizeof(struct sockaddr)-__SOCKADDR_COMMON_SIZE-
sizeof(in_addr_t)-
sizeof(struct in_addr)];
};