网络套接字:socket
一个文件描述符指向一个套接字(该套接字内部由内核借助两个缓冲区实现)
在通信过程中,套接字一定是成对出现的。
网络字节序:
字节在内存中存储的顺序
网络字节顺序是TCP/IP中规定好的一种数据表示格式,它与具体的CPU类型、操作系统无关
从而保证数据在不同主机之间传输时能够被正确解释,网络字节顺序采用大端排序方式
小端法:(PC本地存储)高位存高地址。低位存低地址。 int a=0x12345678
大端法:(网络存储) 高位存低地址。 低位存高地址。
//通过代码检测当前主机的字节序
#include<stdio.h>
int main()
{
// 共用体(Union)
union{
short value; //2字节
char bytes[sizeof(short)];//char[2]
}test;
test.value=0x0102;
if((test.bytes[0]==1)&&(test.bytes[1]==2)){
printf("大端字节序\n");
}else if((test.bytes[0]==2)&&(test.bytes[1]==1)){
printf("小端字节序\n");
}else{
printf("未知\n");
}
return 0;
}
含义:h - host 主机 to - 转换成什么 n - network 网络字节序 s - short转ip
htonl——》主机——》网络(IP) 192.168.1.11–>string–>atoj–>int–>htonl
ntohl——》网络——》主机(IP)
转端口
ntons——》网络——》主机(Port)
htons——》主机——》网络(port)
IP地址转换函数:
int inet_pton(int af,const char *src,void *dst); 本地字节序(string IP)——>网络字节序
af:AF_INET、AF_INET6
src:传入,IP地址(点分十进制)
dst:传出,转换后的 网络字节序的 IP地址。
返回值:
成功: 1
异常: 0,说明src指向的不是一个有效的IP地址
失败:-1
const char *inet_ntop(int af,const void *src,char *dst,socklen_t size); 网络字节序—>本地字节序(string IP)
af:AF_INET、AF_INET6
src:网络字节序IP地址
sdt:本地字节序(string IP)
size:dst的大小。
返回值:
成功:dst.
失败:NULL
sockaddr地址结构:
socket地址是一个结构体,封装端口号和IP等信息。
客户端->服务器(IP,port)
struct sockaddr_in addr;
addr.sin_family=AF_INET/AF_INET6 man 7 ip
addr.sin_port=htons(9527);
int dst;
inet_pton(AF_INET,"192.157.22.45",(void *)&dst);
【*】addr.sib_add.s_addr=htonl(INADDR_ANY); 取出系统中有效的任意IP地址。二进制类型
bind(fd,(struct sockaddr*)&addr,size);
socket函数:
#include<sys/socket.h>
int socket(int domain,int type,int protocol); 创建一个套接字
domain:AF_INET、AF_INET6、AF_UNIX
type:SOCK_STREAM、SOCK_DGRAM
protocol:0
返回值:
成功:新套接字所对应文件描述符
失败:-1 errno
bind函数:
#include<arpa/inet.h>
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); 给socket绑定一个 地址结构(IP+port)
sockfd:socket 函数返回值
struct sockaddr_in addr;
addr.sin_family=AF_INET;
addr.sin_port=htsns(8888);
addr.sin_addr.s_addr=htonl(INADDR_ANY);
addr:(struct sockaddr*)&addr
addrlen:sizeof(addr)地址结构的大小。
返回值:
成功:0
失败:-1 errno
listen函数:
int listen(int sockfd,int backlog); 设置同时与服务器建立连接的上限数。(同时进行3次握手的客户端数量)
sockfd:socket 函数返回值
backlog:上限数值。最大值 128
返回值:
成功:0
失败:-1 errno
accept函数:
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); 阻塞等待客户端建立连接,成功的话,返回一个与客户端成功连接的socket文件描述
sockfd:socket 函数返回值
addr:传出参数。成功与服务器建立连接的那个客户端的地址结构(IP+port)
socklen_t clit_addr_len=sizeof(addr);
addrlen:传入传出。&clit_addr_len
入:addr的大小。出:客户端addr实际大小。
返回值:
成功:能与服务器进行数据通信的socket对应的文件描述。
失败:-1,errno
connect函数:
int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen); 使用现有的socket与服务器建立连接
sockfd:socket 函数返回值
struct sockaddr_in srv_addr; //服务器地址结构
struct.sin_family=AF_INET;
srv_addr.sin_port=9527 跟服务器bind时设定的port完全一致
inet_pton(AF_INET,"服务器的IP地址",&srv_addr.sin_addr.s_addr);
addr:传入参数。服务器地址结构
addrlen:服务器的地址结构大小
返回值:
成功:0
失败:-1 errno
如果不使用bind绑定客户端地址结构,采用“隐式绑定”。