UC学习day12 基于tcp的网络编程

一 基于tcp的网络编程
四次分手
编程模型
服务器端
1 创建通讯设备(端点),返回该端点的文件描述符sfd.socket(2)
2 将sfd和服务器的ip地址 端口号绑定 bind(2)
3 将sfd设定为被动连接状态,监听客户端连接的到来.将到来的连接放入未决连接队列中.listen(2)
while(1){
4 从未决连接队列中取出一个进行处理,返回和客户端的连接描述符cfd.如果未决连接队列中没有数据,阻塞等待. accept(2)
5 从cfd中读取客户端的数据 read(2)
6 处理客户端的数据
7 将处理结果通知给客户端 write(2)
8 关闭cfd.切记不能关闭sfd. close(2)
}

客户端的模型
1 创建通讯端点,返回该端点的文件描述符 fd socket(2)
2 使用该端点向服务器发起连接 connect(2)
3 使用该端点向服务器发送消息 write(2)
4 阻塞等待服务器的响应消息 read(2)
5 处理响应结果
6 关闭本次连接 close(2)

socket(2) bind(2) listen(2) accept(2) connect(2)

#include <sys/types.h> /*See NOTES */
#include <sys/socket.h>
int socket(int domain, int type, int protocol);
功能:创建一个通讯端点,返回一个描述符
参数:
domain:
AF_INET IPv4 Internet protocols ip(7)
AF_INET6 IPv6 Internet protocols ipv6(7)
type:
SOCK_STREAM:有序的 可靠的 双向的 基于连接的字节流 TCP
SOCK_DGRAM: 不可靠 无需连接的 数据包 UDP

protocol: 0

返回值:
成功 返回一个新的文件描述符,用于socket的.
错误 -1 errno被设置为相应的错误码

bind(2)
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);
功能:绑定一个名字到socket
参数:
sockfd:指定文件描述符.将地址绑定到这个文件描述符
addr:指定了具体的地址 实际传送进来的结构体取决于地址家族

addrlen:指定了addr的内存空间大小
返回值:
成功 0
错误 -1 errno被设置为相应错误码

通用地址家族
struct sockaddr{
sa_family_t sa_family;
char sa_data[14];
};

#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int listen(int sockfd, int backlog);
功能:将sockfd设定为被动连接状态,监听客户端的连接.
有客户端连接到来的时候,将新来的连接放入到未决连接队列中
参数:
sockfd:指定文件描述符 SOCK_STREAM
backlog:指定了最大未决连接数
返回值:
成功 0
错误 -1 errno被设置为相应错误码

#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
功能:从未决连接队列中取出一个进行连接处理.返回一个新的连接描述符.
参数:
sockfd:指定socket.从这个socket的未决连接队列中取出一个
addr:客户端的地址被填充到这个参数指定的空间里.

addrlen:值-结果参数,使用之前必须使用addr的大小初始化这个值,函数调用完毕会使用实际的结构体的尺寸填充到这里.
如果addr指定为NULL,addrlen也被指定为NULL.不需要存储客户端的信息.
返回值:
成功 返回一个新的连接描述符
失败 -1 errno被设置为相应的错误码

#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);
功能:在socket发起一个连接,连接到目标地址
参数:
sockfd:指定具体的socket,在这个socket上发起连接
addr:指定了目标地址.
addrlen:指定了addr参数的空间大小
返回值:
成功 0
错误 -1 errno被设置

ipv4地址家族 ipv6地址家族
#include <netinet/in.h>
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 /
};
大端和小端 网络字节序必须是大端
/
Internet address. /
struct in_addr {
uint32_t s_addr;
/
address in network byte order */
};

uint32_t unsigned int;
sin_port_t unsigned short;

端口号是大端字节序的无符号短整型
htonl(3)
#include <arpa/inet.h>
uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);
to
h host
n net
l long
s short

ip地址是网络字节序的无符号整型 binary
192.168.1.123 点分十进制的字符串 text
text<—>binary
inet_pton(3) inet_ntop(3)
#include <arpa/inet.h>
const char *inet_ntop(int af, const void *src,
char *dst, socklen_t size);
功能:binary—>text
参数:
af:指定了具体的地址家族
AF_INET ipv4
AF_INET6 ipv6
src:struct in_addr sin_addr
dst:存储转换后的结果,将转换后的字符串存储到这里
size:指定了dst有效空间大小
返回值:
错误 NULL errno被设置为相应的错误码
成功 返回字符串的首地址.dst指向的地址

#include <arpa/inet.h>
int inet_pton(int af, const char *src, void *dst);
功能:text—>binary
参数:
af:
AF_INET
AF_INET6
src:指定ip地址字符串
dst:存储转换后的结果
返回值:
成功 1
0 ip地址无效
错误 -1 errno被设置

猜你喜欢

转载自blog.csdn.net/weixin_43789711/article/details/90112951