socket套接字、基于TCP的编程模型与实际运用(网络聊天室)
程序员文章站
2022-06-30 19:12:36
...
socket
套接字,是一种接口技术,它封装了TCP/IP通信协议,使用它可以让计算机之间通过网络传输数据,所有的操作系统都是基于socket的接口进行网络通信的。
不光可以用于网络间通信,还可以用于进程间通信,或者可以理解为不同计算机之间的进程间通信。
其实是一个内存对象,以文件描述符的形式呈现,发送数据即写文件,接收数据即读文件
int socket(int domain, int type, int protocol);
功能:创建一个socket对象
domain:地址域,什么类型的地址
AF_UNIX,AF_LOCAL 接收下将使用路径地址进行进程间通信
AF_INET 使用ipv4地址进行网络通信
AF_INET6 使用ipv6地址进行网络通信
type:
SOCK_STREAM 使用数据流进行通信 TCP
SOCK_DGRAM 使用数据报进行通信 UDP
protocol:
特殊的通信协议,一般不用,写0即可。
返回值:成功返回socket描述符,失败返回-1。
通信地址
//基本地址
struct sockaddr {
sa_family_t sa_family; //地址域
char sa_data[14];
};
//本地类型地址
struct sockaddr_un {
sa_family_t sun_family; //地址域 与domain一致即可
char sun_path[108]; //socket文件路径
};
//网络类型地址
struct sockaddr_in {
sa_family_t sin_family; //地址域 与domain一致即可
in_port_t sin_port; //端口号,注意要的是大端数据,2字节
struct in_addr sin_addr; //ip地址
};
//ip地址
struct in_addr {
in_add_r s_addr; //ip地址的整数,注意要的是大端数据,4字节
};
地址字节序转换成网络字节序
uint32_t htonl(uint32_t hostlong);
功能:把地址字节序的4字节整数转换成网络字节序
uint16_t htons(uint16_t hostshort);
功能:把地址字节序的2字节整数转换成网络字节序
uint32_t ntohl(uint32_t netlong);
功能:把网络字节序的4字节整数转换成地址字节序
uint16_t ntohs(uint16_t netshort);
功能:把网络字节序的2字节整数转换成地址字节序
ip地址转换
in_addr_t inet_addr(const char *cp);
功能:把点分十进制的ip地址字符串转换成网络字节序的4字节整数
char *inet_ntoa(struct in_addr in);
功能:把4字节整数的网络字节序转换成点分十进制的ip地址字符串
基于TCP的编程模型
服务端(等待连接的) | 客户端(发起连接的) | 用到的函数 |
---|---|---|
创建socket对象 | 创建socket对象 | socket |
准备地址(自己的) | 准备地址(服务端) | socketaddr_in |
地址与socket绑定 | … | bind |
监听并设置排除的数量 | … | listen |
等待连接 | 连接服务端 | accept/connect |
创建线程或进程给服务客户端 | … | fork/pthread_create |
收发数据 | 收发数据 | read/write |
关闭 | 关闭 | close |
int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
功能:绑定地址域与socket对象
sockfd:socket对象描述符
addr:地址结构体指针,实际参数应该是 struct sockaddr_un*
或者 struct sockaddr_in* 因此需要强制类型转换
addrlen:地址结构体的字节数,以此区别是什么类型的地址。
返回值:成功返回0,失败返回-1
int listen(int sockfd, int backlog);
sockfd:socket对象描述符
backlog:代排队的 数量
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
功能:用于接收链接的客户端
sockfd:绑定后的socket对象描述符
addr:储存客户端的地址,实际参数应该是 struct sockaddr_un*
或者 struct sockaddr_in* 因此需要强制类型转换
addrlen:即是输入也是输出
输入:使用的是什么类型的地址结构接收的
输出:实际接收到的地址结构类型
返回值:与客户端建立链接的socket对象描述符,凭此收发数据,失败返回-1