c-s模型
1. 循环服务器
服务器
创建套接字
绑定IP地址和端口号
启动监听
接收客户端的连接请求
while(1){
处理客户端请求,读写数据
}
关闭连接
客户端
创建套接字
请求连接
while(1){
读写数据
}
关闭连接
函数
-
创建套接字
#include <sys/types.h>
#include <sys/socket.h>int socket(int domain, int type, int protocol);
参数1:指定协议族
AF_INET参数2:套接字类型
SOCK_STREAM - 流式套接字 - TCP
SOCK_DGRAM - 数据报套接字 - UDP
SOCK_RAW - 原始套接字
参数3:协议编号
0
返回值:成功 - 套接字
失败 - -1,设置errno -
绑定IP地址和端口号
int bind(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);
参数1:套接字
参数2:地址结构体
struct sockaddr{
sa_family_t sa_family;
char sa_data[14];
}
赋值使用下面的结构体
struct sockaddr_in{
short sin_family;
short sin_port; //2个字节,端口号
struct in_addr sin_addr; //4个字节,IP地址
unsigned ch ar sin_zero[8]; //预留
};
typedef uint32_t in_addr_t;
struct in_addr {
in_addr_t s_addr;
};
参数3:地址结构的长度
返回值:成功 - 0
失败 - -1,设置errnoIP地址的转化
1. 点分十进制转化为无符号整型
int inet_aton(const char *cp, struct in_addr *inp);
参数1:要转化的点分十进制IP地址 “192.168.1.40”
参数2:保存转化后的无符号整型值 - 网络字节序
返回值:成功/失败
255.255.255.255 - 有效地址in_addr_t inet_addr(const char *cp);
参数:要转化的点分十进制IP地址
返回值:转化后的无符号整型值 - 网络字节序
255.255.255.255 - 无效地址in_addr_t inet_network(const char *cp);
主机字节序 -
无符号整型转化为点分十进制形式
char *inet_ntoa(struct in_addr in);
参数:整型值
返回值:转化后的点分十进制形式
int main(){
int ret;
struct in_addr s;ret = inet_aton(“127.0.0.1”, &s);
printf(“ret: %d, %x\n”, ret, s);
printf("%x\n", inet_addr(“127.0.0.1”));
printf("%x\n", inet_network(“127.0.0.1”));
printf("%s\n", inet_ntoa(s));
printf("%x\n", inet_addr(“255.255.255.255”));
}
3. 启动监听
将进程编程服务器进程,能够接受其他进程的连接请求
int listen(int sockfd, int backlog);
参数1:套接字
参数2:监听的最大值,能够处理多少个连接请求
返回值:成功 - 0
失败 - -1,设置errno
套接字变为监听套接字 -
等待客户端连接请求
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
参数1:监听套接字
参数2:客户端的地址结构
参数3:客户端的地址结构的长度
返回值:成功 - 读写套接字
失败 - -1,设置errno
如果没有连接会阻塞等待连接 -
请求连接
int connect(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);
参数1:套接字
参数2:服务器的地址结构
参数3:地址结构的长度
返回值:返回值:成功 - 0
失败 - -1,设置errno -
发送数据 write
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
参数1:读写套接字
参数2:写的数据存放的首地址
参数3:写的数据的长度 - 字节
参数4:标志
MSG_DONTWAIT:非阻塞
0:不使用标志 - 阻塞
返回值:成功 - 发送的数据的数目
失败 - -1,设置errno -
接收数据 read
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
参数1:读写套接字
参数2:存放读取的数据的首地址
参数3:读取的数据的长度 - 字节
参数4:标志
MSG_DONTWAIT:非阻塞
0:不使用标志 - 阻塞
返回值:成功 - 读取的字节数
失败 - -1,出错,errno
0 - 连接断开