在介绍套接字前,我们需要了解什么是IP地址,什么是端口号port:
1.IP地址
ip协议有两个版本,IPv4 和 IPv6 (一般情况下使用IPv4);
IPv4协议占32个bit;IPv6占128个bit是IPv4的4倍;
1) IP地址是在IP协议中用来标识网络中不同主机的地址;
2) 对于IPv4来说,IP地址是一个4字节,32位的整数
3) 我们通常也是用“ 点分十进制 ”的字符串表示IP地址,例如 192.168.0.1 ;用点分割的每一个数字表示一个字节,范围是 0 ~ 255;
2.端口号
端口号是传输层协议的内容;
1)端口号是一个2字节16位的整数
2)端口号用来标识一个进程,告诉操作系统,当前的这个数据要交给哪一个进程来处理;
3)IP地址+端口号 能够标识网络上的某一台主机的某一个进程
4)一个端口号只能被一个进程占用
(注:一个进程可以绑多个端口号,但一个端口号只能被一个进程绑定;)
一、套接字简单介绍
1.什么是套接字
在Unix/Linux中,一切皆文件。那对于这两个操作系统而言,“端点”就是一个特殊的文件,也就是说Socket实际上就是文件。既然Socket是文件,那就可以用“打开open –> 读写write/read –> 关闭close”模式来操作它,一些socket函数就是对其进行的操作(读/写IO、打开、关闭)
2.对于一个Socket而言,它至少需要3个参数来指定:
1)通信的目的地址;
2)使用的传输层协议(如TCP、UDP);
3)使用的端口号。
3.套接字类型是指创建套接字的应用程序要使用的通信服务类型。linux系统支持多种套接字类型,最常用的有以下三种:
1)SOCK_STREAM:流式套接字,提供面向连接、可靠的数据传输服务,数据按字节流、按顺序收发,保证在传输过程中无丢失、无冗余。TCP协议支持该套接字。
2)SOCK_DGRAM:数据报套接字,提供面向无连接的服务,数据收发无序,不能保证数据的准确到达。UDP协议支持该套接字。
3)SOCK_RAW:原始套接字。允许对低于传输层的协议或物理网络直接访问,例如可以接收和发送ICMP报文。常用于检测新的协议。
4.套接字(socket)编程接口
//创建socket文件描述符(TCP/UDP,客户端 + 服务器)
int socket(int domain,int type,int protocol);
//绑定端口号(TCP/UDP,服务器)
int bind(int socket,const struct sockaddr* address,socklen_t address_len);
//监听(TCP,服务器)
int listen(int socket,int bakclog);
//接受请求,生成新的套接字(TCP,服务器)
int accept(int socket,struct sockaddr* address,socklen_t addrlen);
//建立连接(TCP ,服务器)
int connect(int socket,const struct sockaddr* addr,socklen_t addrlen);
//sockaddr结构
struct sockaddr
{
_SOCKADDR_COMMON( sa_ );
char sa_data[14];
}
//sockaddr_in结构
struct sockaddr_in
{
_SOCKADDR_COMMON(sin_);
in_port_t sin_port;
struct in_addr sin_addr;
unsigned char sin_zero[sizeof(struct sockaddr)-
_SOCKADDR_COMMON_SIZE-
sizeof(in_port)-
sizeof(struct in_addr)];
};
//在基于IPv4编程时,使用的数据结构是sockaddr_in;这个结构体里主要有三部分信息:地址类型、端口号、IP地址
//in_addr结构
typedef uint32_t in_addr_t;
struct in_addr
{
in_addr_t s_addr;
};
//in_addr用来表示一个Ipv4的Ip地址。就是一个32位的整数。
5.网络协议中的字节序
所有的网络协议为了统一,全都使用的是大端存储——>下面介绍几个字节序转换函数
#include<arpa/inet.h>
uint32_t htonl(uint32_t hostlong); //主机序列转换成网络序列
uint16_t htons(uint16_t hostshort); //主机序列转换成网络序列
uint32_t ntohl(uint32_t netlong);