特点
有连接:通信双方需要事先连接成功,方可传输数据
有确认:一方收到对端的任何数据,都会给另一方发
回执确认
保证数据有序、不重复、丢失会重发
如果网络拥堵,会自动调节发送量
采用帧异步的流式通信方式
流程
一. TCP服务器
1创建套接字
int
socket
(
int
domain
,
int
type
,
int
protocol
);
domain
:
网络协议 AF_INET (IPv4地址适用)
type
:
传输协议
SOCK_STREAM (TCP选用)
protocol
:
属性默认为
0
返回值
:
成功
文件描述符
失败
-
1
2绑定服务器地址(服务区必须为其绑定一个地址不然它自己随机得到的地址我们不知道就无法连接服务器)
int
bind
(
int
sockfd
,
const struct
sockaddr
*
addr
,
socklen_t addrlen
);
sockfd
:
服务器对象
addr
:
服务器地址
addrlen
:
服务器地址长度
返回值
:
成功
0
失败
-
1
struct
sockaddr_in
{
sa_family_t sin_family
;
/*
服务器地址类型
:
AF_INET->IPV4
类型
*/
in_port_t sin_port
;
/*
服务器的端口号
*/
struct
in_addr sin_addr
;
/*
服务器的
IP
地址
*/
};(使用时用这个结构体,传给函数时强转为
struct
sockaddr*类型不然会警告
)
一般的
IP
地址都是以点分制编写的如
:
192.168
.
64.1
#include <arpa/inet.h>
把字符串
IP
转换为
uint32_t
IP
in_addr_t
inet_addr
(
const
char *
cp
);
把
uint32_t IP
转换为字符串
IP
char *
inet_ntoa
(
struct
in_addr in
);
网络通信都采用大端序
uint16_t
htons
(
uint16_t
hostshort
);
//
把本地
序转换为网序
uint16_t
ntohs
(
uint16_t
netshort
);
//
把网络
序转换为本地序
3设置为监听模式
int
listen
(
int
sockfd
,
int
backlog
);
sockfd
:
服务器对象
backlog
:
同时支持多少个用户链接。
backlog
最大值可设至
128
。
返回值
:
成功
0
失败
-
1
4接收客户端连接
int
accept
(
int
sockfd
,
struct
sockaddr
*
addr
,
socklen_t
*
addrlen
);
sockfd
:
服务器对象
addr
:
对方(发起请求者)
IP
地址信息
addrlen
:
对方(发起请求者)
IP
地址的大
小
返回值
:
返回一个 新的
socket(连接进来的TCP客户端的文件描述符)
失败
-
1
当不需要得到对方的地址信息时最后的两个参数可以设置为null(除了在accept接收对方的ip和端口信息还可以用getpeername(sockfd, (struct sockaddr *)&sa, &len)函数,根据套接字描述符获取其IP信息)
二. TCP客户端
1创建套接字
int
socket
(
int
domain
,
int
type
,
int
protocol
);
domain
:
网络协议 AF_INET (IPv4地址适用)
type
:
传输协议
SOCK_STREAM (TCP选用)
protocol
:
属性默认为
0
返回值
:
成功
文件描述符
失败
-
1
2连接服务器
int
connect
(
int
sockfd
,
const struct
sockaddr
*
addr
,
socklen_t addrlen
);
sockfd
:
网络文件描述符
addr
:
需要连接的服务器地址信息
(你要打电话给某人必须要知道他的电话号码)
addrlen
:
地址长度
返回值
:
成功
0
失败
-
1
3.read/write
读写
or send/recv
发送接收
ssize_t
send
(
int
sockfd
,
const
void
*
buf
,
size_t
len
,
int
flags
);
TCP
服务器端设计流程
1.socket
创建服务器对象
sockfd
:
需要发送的网络文件描述符
buf
:
数据缓存区
len
:
数据的大小
flags
:
一般设
0