【7】 TCP编程流程
服务器端:
1) socket(),创建套接字文件,用于连接
2) bind(), 绑定,把socket()函数返回的文件描述符和IP、端口号进行绑定;
3) listen(), (监听)将socket()返回的文件描述符的属性,由主动变为被动;
4) accept(), 阻塞函数,阻塞等待客户端的连接请求,如果有客户端连接,
则accept()函数返回,返回一个用于通信的套接字文件;
5) recv(), 接收客户端发来的数据; read()
6) send(), 发送数据;
7) close(), 关闭文件描述符;连接、通信
客户端:
1) socket(),创建套接字文件,既用于连接,也用于通信;
2) connect(); 用于发起连接请求;
3) send(), 发送数据;
4) recv(), 接收数据;
5) close(), 关闭文件描述符;
【9】socket
socket - create an endpoint for communication //创建通信端点
SYNOPSIS
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int socket(int domain, int type, int protocol);
功能: 创建套接字文件
参数:
domain:协议族
AF_UNIX, AF_LOCAL 用于本地通信
AF_INET IPv4 Internet protocols ip(7)
AF_INET6 IPv6 Internet protocols ipv6(7)
type:协议类型
SOCK_STREAM TCP
SOCK_DGRAM UDP
protocol:
一般情况下写0
系统默认自动帮助匹配对应协议
传输层:IPPROTO_TCP、IPPROTO_UDP、IPPROTO_ICMP
网络层:htons(ETH_P_IP|ETH_P_ARP|ETH_P_ALL)
返回值:
成功: 返回一个文件描述符;
失败: -1
【10】bind
int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
功能: 绑定,将socket()返回值和IP/端口号进行绑定;
参数:
1. sockfd: 是socket()函数的返回值;
2. const struct sockaddr *addr: //把端口号和IP填充进去。
struct sockaddr是结构体类型,是一个通用结构体;
struct sockaddr {
sa_family_t sa_family; // 2个字节typedef unsigned short int sa_family_t; //
char sa_data[14]; // 14字节
}
整个结构体大小为16个字节
******在填充的时候填充 struct sockaddr_in ;
struct sockaddr_in {
unsigned short sin_family; //协议IPv4, 2个字节
unsigned short sin_port; //端口号 , 2个字节
struct in_addr sin_addr; //一个IP,多字节需要转换为网络字节序。
struct in_addr {
__be32 s_addr; //IP地址,4个字节
};/* Pad to size of `struct sockaddr'. */
unsigned char __pad[__SOCK_SIZE__ - sizeof(short int) -
sizeof(unsigned short int) - sizeof(struct in_addr)];//8个字节
};
addrlen:
结构体的大小;
sizeof(serveraddr);
返回值:
-1 失败
【11】listen
int listen(int sockfd, int backlog);
功能: 用于监听,将主动套接字变为被动套接字;
参数:
sockfd: socket()的返回值
backlog:客户端同时连接服务器的最大个数;(队列1:保存正在连接)
(队列2,连接上的客户端)
5 6 7 8
返回值:
失败 -1
【12】 accept
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
阻塞函数,阻塞等待客户端的连接请求,如果有客户端连接,
则accept()函数返回,返回一个用于通信的套接字文件;
参数:
sockfd
addr: 如果不需要关系具体是哪一个客户端,那么可以填NULL;
addrlen:如果不需要关系具体是哪一个客户端,那么可以填NULL;
返回值:
文件描述符;
acceptfd;
【13】 recv
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
功能: 接收数据
参数:
sockfd: acceptfd ;
buf 存放位置
len 大小
flags 一般填0
作业:
1. 实现服务器代码,使用telnet工具测试
telent IP 端口号
2. 尝试实现客户端代码;
inet_addr()
功能同上,返回转换后的地址。
in_addr_t inet_addr(const char *strptr);
inet_ntoa()
将32位网络字节序二进制地址转换成点分十进制的字符串。
char *inet_ntoa(stuct in_addr inaddr);
主机字节序到网络字节序
u_long htonl (u_long hostlong);
u_short htons (u_short short);
网络字节序到主机字节序
u_long ntohl (u_long hostlong);
u_short ntohs (u_short short);