一、cs架构
服务器 客户端
创建套接字 -----socket() 创建套接字----socket()
绑定本机ip和端口号-----bind()
创建套接字监听------listen()
等待连接-----accept() 发起连接-------connect()
接发数据----read()/write() 接发数据-------read()/write()
关闭套接字-----close() 关闭套接字------close()
二、服务器的TCP编程
①创建套接字
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>函数原型:
int socket(int domain, int type, int protocol);
参数:
domain:地址族 //每一个不同的协议,地址结构不同
AF_UNIX: 域套接字
AF_INET:IPV4协议 //=PF_INET(重定义)
AF_INET6:IPV6协议
type:套接字类型
SOCK_STREAM:流式套接字 -- 唯一对应tcp通信
SOCK_GDRAM:数据报套接字 -- 唯一对应udp通信
protocol:
默认值填0;
返回值:
成功返回一个套接字,失败返回-1;
②绑定ip和端口号
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>函数原型:
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
参数:
sockfd:socket创建得到的套接字
addr: 服务器的地址结构首地址
addrlen:服务器地址结构的大小
返回值:成功返回0,失败返回-1;
IPV4对应的地址结构:
struct sockaddr_in {
sa_family_t sin_family; /* address family: AF_INET */
in_port_t sin_port; /* port in network byte order */
struct in_addr sin_addr; /* internet address */
};
struct in_addr {
uint32_t s_addr; /* address in network byte order */
};
s_addr才是绑定ip地址的变量
例:
struct sockaddr_in saddr;
saddr.sin_family = AF_INET; //ipv4协议
saddr.sin_port = 8888; //设置端口号为8888
saddr.sin_addr.s_addr = inet_addr("192.168.7.220"); //将点分十进制的地址转换为整型再赋值注意:ip有两种表达方式,一种是点分十进制,一种是二进制。
相关转换函数为:inet_addr(点分十进制转二进制) inet_ntoa(二进制转点分十进制)
③创建套接字监听器
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>函数原型:
int listen(int sockfd, int backlog);
参数:
sockfd:套接字
backlog:客户端连接的最大等待队列长度
返回值:成功返回0,失败返回-1;
④ 等待客户端连接
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>函数原型:
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
参数:
sockfd:socket创建得到的套接字
addr:客户端的地址结构首地址
addrlen: 客户端地址结构的长度的首地址
返回值:
成功返回一个新的套接字(读写套接字),该套接字用于服务器的数据读写,失败返回-1
⑤向服务器连接
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>函数原型:
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
参数:
sockfd:套接字
addr:服务器的地址结构的首地址
addrlen:服务器地址结构的大小
返回值:成功返回0,失败返回-1;