对应书籍

《tcp/ip网络编程》
第四章 基于TCP的服务器端/客户端(1)
第五章 基于TCP的服务器端/客户端(2)

前言

TCP服务器端和客户端函数调用关系图

先看一个关系图, 大概留个印象, 边学边回过头看看.
tcp/ip网络编程[笔记三] - 图1

基本函数listen()、accept()、connect()

在继续编程之前, 先来详细讲解一下这三个重要的函数, 上一章讲了前面的函数.

1. litsen()

tcp/ip网络编程[笔记三] - 图2
 只有调用listen函数,客户端才能调用connect()函数, 如上图所示. listen函数就像创建了一个门卫, 有了这个门卫,客户端就能向这个门卫发送数据包. 门位会把收到的数据放到连接请求等待队列中.

2. accept()

tcp/ip网络编程[笔记三] - 图3
 accept从连接请求队列中取出一个客户端连接请求, 并为次客户端产生一个用户数据I/O的套接字,返回文件描述符.

3. connect()

tcp/ip网络编程[笔记三] - 图4
connect函数比较简单, 和bind()函数有点类似, 看看上面这幅图基本就懂了.
但是需要注意一下几点:

  1. connect()调用成功并不意外服务器调用了accept()函数,只能说明连接请求进入等待队列.
  2. connect()客户端套接字自动绑定地址信息(隐式调用bind())

4. listen()和accept()的区别

 上面的内容基本是摘抄书本上的内容, 现在我自己总结一下. 我之前感觉litsen和accpet意思差不多, 都是去监听一个端口. 看完一章, 我恍然大悟. litsen相当于前台, 而accept就是具体干事的人,前台负责接收用户, 并将用户安排到等待队列, 然后具体干事的人为顾客提供具体服务. 这就有点像我之前看到hustoj, judged对应listen, judge_client对应accept. 当然这个比喻还是和实际稍微有点区别.
 套接字就是基本单位, 就像我们现实生活中的一个人一样. 现在先讲这么多.

迭代回声服务器/客户端

基本要求

  • 服务器在同一时刻只与一个客户单相连,并提供回声服务
  • 服务器端依次向n个客户端提供服务并退出
  • 客户端接收用户输入的字符串并发送到服务器端
  • 服务器端将接收的字符串数据传回到客户端, 即“回声”
  • 用户一直输入, 直到输入Q时, 客户端、服务器端依次关闭

思考before coding

 这次和第一次写的代码, 客户端的主要改变是开始向服务器端传输数据了, 用read()函数就能解决. 服务器的主要改变是, write()的信息是依据客户端传输过来的数据. 这个用一个循环, 不停的从客户端读入消息,再向客户端发送消息即可, 其实挺简单的, 建议自己独立完成.

代码

应用层协议

要求

代码

思考

 写了这个自定义的协议, 我发现其实数据类型之间是可以相互转换的, 只要知道是哪些字节存储的是什么东西就行了. 对于tcp来说, 数据只是字节流而已, 读入数据数据直接存储为char[N]就行, 再通过不同类型的指针, 取出数据即可, 而如何处理这些数据就是应用层的事情了.
 还需要注意一点 (int )p+1 和 (int )(p+1)是不一样的.