Socket通信
Socket类型
- 流失套接字SOCK_STREAM (TCP):面向连接的套接字
- 数据报套接字SOCK_DGRAM (UDP):面向无连接的套接字
- 原始套接字 (SOCK_RAW):对较低层次的协议直接访问,比如
IP
、ICMP
协议
Socket相关概念
- 流 (Stream)
对象间进行数据交换时总是先将数据转换为某种形式的流,再通过流的传输,到达目的对象后再将流转换为对象数据。所以,可以把流看作是一种数据的载体,通过它可以实现数据交换和传输。
- 连接 (Connection)
- 阻塞 (Block)、非阻塞 (Non-block)
阻塞调用是指调用结果返回(或者收到通知)之前,当前线程会被挂起,即不继续执行后续操作;
非阻塞调用指在不能立刻得到结果之前,该调用不会阻塞当前线程。
- 同步 (Synchronous)、异步 (asynchronous)
所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回,同时其它线程也不能调用这个方法。
异步呢,就是发出一个功能调用后,不管没有结果的返回,都不影响当前任务的继续执行。即两个生产线相互独立。
- IP地址 (IP Address)
- 字节顺序 (Bytes Order)
字节顺序是指占内存多于一个字节类型的数据在内存中的存放顺序,通常有小端、大端两种字节顺序。
- 带外数据 (Outband Data)
带外数据,也称为TCP紧急数据,是相连的每一对流套接口间一个逻辑上独立的传输通道。带外数据是独立于普通数据传送给用户的。
TCP/UDP
- TCP:面向连接(如手机通话)、稳定、需要资源多、保证数据正确性、保证数据顺序。
- UDP:面向无连接(如手机发短信)、不稳定、需要资源少、不保证数据顺序。
Sockaddr_in和Sockaddr
Sockaddr_in和Sockaddr在Linux下的结构体分别为
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/* Structure describing an Internet socket address. */
struct sockaddr_in
{
__SOCKADDR_COMMON (sin_);
in_port_t sin_port; /* Port number. */
struct in_addr sin_addr; /* Internet address. */
/* Pad to size of `struct sockaddr'. */
unsigned char sin_zero[sizeof (struct sockaddr) -
__SOCKADDR_COMMON_SIZE -
sizeof (in_port_t) -
sizeof (struct in_addr)];
};
/* Structure describing a generic socket address. */
struct sockaddr
{
__SOCKADDR_COMMON (sa_); /* Common data: address family and length. */
char sa_data[14]; /* Address data. */
};
sockaddr缺陷:sa_data把目标地址和端口信息混在一起了 sockaddr_in:解决sockaddr缺陷,把port和addr分开存储在两个变量中
总结
二者长度一样,都是16个字节,即占用的内存大小是一致的,因此可以互相转化。二者是并列结构,指向sockaddr_in结构的指针也可以指向sockaddr。
sockaddr常用于bind、connect、recv、send等函数的参数,指明地址信息,是一种通用的套接字地址。
sockaddr_in 是internet环境下套接字的地址形式。所以在网络编程中我们会对sockaddr_in结构体进行操作,使用sockaddr_in来建立所需的信息,最后使用强制类型转化就可以了。一般先把sockaddr_in变量赋值后,强制类型转换后传入用sockaddr做参数的函数:sockaddr_in用于socket定义和赋值;sockaddr用于函数参数。