socket是网络编程、网络通信的工具
流式套接字(stream socket)是面向连接的套接字,采用tcp协议
代码中用SOCK_STREAM表示,有几大特征
1、数据在传输过程中不会消失;
2、数据是按顺序发送与到达;
3、数据的发送与接收不一定同步
解释一下特征3:客户端和服务端都有一个缓冲区,达到缓冲区的数据不一定被立即读取,缓冲区满了之后接收端也可以选择一次性读取或者分批次读取。
典型应用:浏览器HTTP协议
数据报套接字(Datagram socket)是无连接的套接字,采用udp协议
代码中用SOCK_DGRAM表示,有几大特征:
1、强调传输速度而非传输顺序;
2、数据传输过程中可能丢失、损毁;
3、限制每次传输的大小;
4、数据的发送和接受是同步的;
典型应用:语音视频通话,强调同步。
socket API
套接口地址结构
大部分套接口函数都需要一个指向套接口地址结构的指针作为参数,每个协议族都定义了它自己的套接口地址结构,都以“sockaddr_”开头。
IPV4套接口地址结构
网际套接口地址结构,以“sockaddr_in”命名,定义在头文件<netinet/in.h>中。
struc in_addr {
in_addr_t s_addr; //32bit IPV4 address, network byte ordered
};
struct sockaddr_in {
uint8_t sin_len; //length of structure(16)
sa_family_t sin_family; //AF_INET
In_port_t sin_port; //16bit TCP/UDP port number
struct in_addr sin_addr; //32bit IPV4 address
char sin_zero[8]; //unused
};
通用套接口地址结构
当作为参数传递给任一个套接口函数时,套接口地址结构总是通过指针来传递,但通过指针来取得此参数的套接口函数必须处理来自所支持的任何协议族的套接口地址结构。
有一个问题是如何声明所传指针的数据类型。ANSI C中有很简单的解决办法,它有通用的指针类型void*,但是,套接口函数是在ANSI C之前定义的,1982年采用了这样一个办法:在<sys/socket.h>头文件中定义一个通用的套接口地址结构
struct sockaddr{
uint8_t sa_len;
sa_family_t sa_family;
char sa_data[14];
};
于是,套接口函数被定义为采用指向通用套接口地址结构的指针,要求这些函数的调用都必须将指向特定协议的调节扣地址结构的指针类型转换成指向通用套接口地址结构的指针;
再说说bind和accept函数中最后一个参数的差别
很显然差别在于传递的是值还是结果,即bind函数中传递只是该指针的大小,而accept函数传递的是指针的地址,也就是可以取得该指针;原因在于bind函数在将套接口地址结构传递给套接口函数的方向是从进程到内核,内核仅需知道指针大小,使得内核在写此结构时不会越界即可;而accept函数传递的 方向是从内核到进程,进程需要知道内核在此结构中确切存储了多少信息。
操纵字节的函数
作用跟C的下列函数相同,只是操纵对象从字符串变成字节