C++中,linux
服务端
-
创建用于监听client的socket(int af, int type, int protocol)
1. af:address family,指定ip类型,用的ipv4还是ipv6
2. type:socket类型,包括sock_stream、sock_dgram,也就对应着tcp 、udp
3. protocol:传输协议用 tcp还是udp。如果type可以推算出protocol来,可以写默认值0。 -
创建 sockaddr_in 结构体,用于指定监听server端哪个接口
struct sockaddr_in {
sa_family_t sin_family; //ip类型
unit16_t sin_port; //port
struct in_addr sin_addr; //ip 地址,服务端一般用127.0.0.1
char sin_zero[8]; //没用到
}
- socket 绑定 sockaddr,socket知道监听哪个端口
bind(serv_sock, //socket
(struct sockaddr*)&serv_addr, //sockaddr_in
sizeof(serv_addr) //sockaddr_in这个结构体占用多少bit
)
- 进入监听状态,设置监听队列大小, 此时还没有阻塞
listen(serv_sock, //socket
20 //它叫backlog,表示request queue的大小。
)
- 阻塞自己,监听client端的请求
可以获取2个值:
1. clent端的sockent
2. client端的 sockadd_in 地址
3. client端的sockadd_in 的大小
int accept( // 返回值是client端的sockent
serv_socket, //服务端的socket
(struct sockaddr*)&client_addr, // 本地创建一个变量client_addr,作为参数传过去
&client_addr_size //本地变量,获取到sockaddr的大小
)
-
通过(5),就获取到了client端的socket。
此时就可以用client_socket来读写数据了 -
最后要关闭 serverSocket 和 clientSocket
client
- 创建serverSocket,用于与serverSocket通信
- 创建 socketAddress,包含ip和port,表明要与哪个server通信
- 连接 server端。执行完connect后,serverSocket就与server成功连接了
connect(serverSocket, //服务端的socket
(struct sockaddr*)&serv_addr, //服务端的socketAddress
sizeof(serv_addr) // socketAddress的大小
)
- 在(3)之后,serverSocket就可以读写了
- 关掉serverSocket
使用socket读写
只要获取到对方的socket,就可以使用write(…) \ read(…)来读写了
// 把*buffer里,size字节长度的数据,写入到socket里
write(socket, *buffer, size);
// 从socket里,取出size字节长度的数据,写入到buffer里。
read(socket, *buffer, size);
读写缓存
write\ read时,是写入writeCache,从readCache读取。
写缓存
- tcp正在发送数据,则writeCache锁定,此时执行write会阻塞等待发送完数据
- write数据 > writeCache可用空间,阻塞,tcp把数据发送出去再写入。
- write的数据 > writeCache最大空间,自动分批写入。
读缓存
- readCache里有就读,没有就阻塞
- read的size < 缓存里数据大小,则只读read指定的size,其他数据继续保存在readCache
- read的size > 缓存里数据大小,不知道?