第八章 面向连接的通信(TCP)
1 Echo socket示例程序
创建项目,添加原生支持
2 用tcp实现面向连接的通信
//创建socket
intsocket(int domain,//产生通信的socket域
int type,//指定通信的类型
int protocol);//指定会用到的协议
Domain: PF_LOCAL 主机内部通信协议族
PF_INETinternet第四版协议族
Type: SOCK_STREAM 提供tcp 面向连接的stream socket
SOCK_DGRAM 提供udp无连接的datagram socket
//socket与地址绑定
intbind(int socketDescriptor,//socket实例
conststructsockaddr * address,//被绑定的协议地址
Int addressLength);//协议地址结构的大小
不同的协议族使用不同的协议地址,PF_INET使用sockaddr_in
结构体定义如下:
#define __SOCK_SIZE__ 16
structsockaddr_in {
sa_family_tsin_family;
unsignedshortintsin_port;
structin_addrsin_addr;
unsignedchar__pad[__SOCK_SIZE__- sizeof(shortint) -
sizeof(unsignedshortint) - sizeof(structin_addr)];
};
网络字节排序:在硬件层,不同的机器体系结构使用不同的数据排序
以arm为例,每个字单元包含四个字节单元或两个半字单元
Big-endian
对于地址为a的字节单元,包含a,a+1,a+2,a+3, 由高到低a,a+1,a+2,a+3
对于地址为a的半字单元,包含a,a+2 ,由高到低为a,a+2
Little-endian
对于地址为a的字节单元,包含a,a+1,a+2,a+3, 由高到低a+3,a+2,a+1,a
对于地址为a的半字单元,包含a,a+2 ,由高到低为a+2,a
注:字节排序不同的机器不能直接交换数据,为了使其能通信,ip将big-endian声明为官方数据传输网络字节排序规则
Java虚拟机使用big-endiian
Arm和x86使用little-endian
Mips使用big-endian
原生程序处理字节排序转换
#include<sys/endian.h>
Htons: 将unsigned short从主机字节排序转换到网络字节排序
Ntohs: 与htons相反
Htonl: 将unsigned integer从主机字节排序转换到网络字节排序
Ntohl: 与htonl相反
监听接入的连接
intlisten(int socketDescriptor,//socket实例
int backlog);// 指定保存挂起的输入连接的队列大小
即队列中挂起的连接数的最大值
接受传入连接
intaccept(int socketDescriptor,// socket实例
structsockaddr * address,// 被绑定的协议地址
socklen_t * addressLength);// 协议地址大小
从socket接收数据
ssize_trecv(int socketDescriptor,//socket实例
void * buffer,//内存地址指针,保存socket数据
size_t bufferLength,//指定缓冲区大小
unsignedint flags);//指定接收所需要的额外的标志
向socket发送数据
ssize_tsend(int socketDescriptor,//
constvoid * buffer,//
size_t bufferLength,//
unsignedint flags);//