1. 前言
在看着这篇博客之前,希望各位还是有一些计算机网络基础。还有一些C++的入门基础,不然会看的一头雾水。
2. 套接字简单介绍
目前国际比较通用的为五层协议,即物理层,数据链路层,网络层(IP),传输层(TCP/UDP),应用层。
下层为上层提供服务,上层的实现有需要下层为其提供服务。这里就不做深入的介绍,这要将个套接字。
在运输层中,TCP连接的端点称为套接字或插口,端口号拼接到IP地址则形成套接字。
套接字 socket = {IP地址:端口号}
每一条TCP连接唯一地被通信两端的两个端点(两个套接字)所确定,即:
TCP连接 ::= {socket1,socket2} = {(IP1:PORT1),(P2:PORT2)}
3. 端口号的介绍
端口号分为两类:
(1)服务器使用的端口号:
包括熟知端口号或系统端口号,数值为0~1023。
应用程序 | FTP | TELNET | SMTP | DNS | TFTP | HTTP | SNMP | SNMP(TRAP) | HTTPS |
熟知端口号 | 21 | 23 | 25 | 53 | 69 | 80 | 161 | 162 | 443 |
以及登记端口号,数值为1024~49151。
(2)客户端使用的端口号:数值为49152~65535
4. 创建Socket套接字
/* Create a new socket of type TYPE in domain DOMAIN, using
protocol PROTOCOL. If PROTOCOL is zero, one is chosen automatically.
Returns a file descriptor for the new socket, or -1 for errors. */
extern int socket (int __domain, int __type, int __protocol) __THROW;
这是C++Socket函数的原型,定义于<sys/socket.h>中。
参数 :
__domain为地址家族,一般填写AF_NET
__type为类型,比如TCP则为SOCKET_STREM,UDP则为SOCKET_DGRAM。(觉得这一点和python很想。虽然Java连接socket的时候是直接选择TCP类或UDP类然后给予IP地址和端口号就可以了。)
__protocol为协议编号,一般为0。(说真的,我也不知道这个是干嘛的!)
返回:
一个套接字的标识符。每个套接字都有唯一的标识符。
5. 绑定IP地址(bind)
/* Give the socket FD the local address ADDR (which is LEN bytes long). */
extern int bind (int __fd, __CONST_SOCKADDR_ARG __addr, socklen_t __len)
__THROW;
像前面说的那样,要是两个地方的主机连接起来,需要有IP地址和端口号来识别。IP地址确定主机,端口号确定主机里面的进程,即需要把数据交付给哪个主机的哪个进程。bind可以将socket和IP地址绑定起来,意思差不多就是这样。
参数:
__fd为套接字的唯一标识符,就是上面的返回值。
__addr简单的理解为一个封装了IP地址和端口号的结构体。以下会继续介绍。
__len为上面__addr的长度,直接sizeof(struct sockaddr),