创建收发文件的服务器端 客户端,<TCP/IP网络编程> Chap.5 基于TCP的服务器端/客户端(2)...

已知字符串长度情况下完善回声客户端

# gcc echo_client2.c -o eclient2

# ./eclient2 127.0.0.1 9190

Connected

Input message (Q to quit): orange

Message from server: orange

Input message (Q to quit): hhhhhhhhhhhhhhhhhhhhhhhhhhhh

Message from server: hhhhhhhhhhhhhhhhhhhhhhhhhhhh

Input message (Q to quit): q

服务端同上一章。

定义应用层协议

原书中有些bug,服务端接收到的操作数个数没有转换成int。经fix后代码见附录,运行结果如下:

# ./opserver 9190

Connected client 1

Connected client 2

Connected client 3

# ./opclient 127.0.0.1 9190

Connected

Input operand count: 3

Input operand: 1

Input operand: 5

Input operand: 9

Input operator: +

Operation result: 15

# ./opclient 127.0.0.1 9190

Connected

Input operand count: 4

Input operand: 16

Input operand: 8

Input operand: 4

Input operand: 2

Input operator: -

Operation result: 2

# ./opclient 127.0.0.1 9190

Connected

Input operand count: 2

Input operand: 5

Input operand: 7

Input operator: *

Operation result: 35

TCP原理

I/O缓冲特性:

I/O缓冲在每个TCP套接字中单独存在。

I/O缓冲在创建套接字时自动生成。

即使关闭套接字也会继续传递输出缓冲区中的遗留数据。

关闭套接字将丢失输入缓冲区中的遗留数据。

习题

请说明TCP套接字连接设置的三次握手过程。尤其是3次数据交换过程每次收发的数据内容。

1)A向B发起连接,发送SYN包(SYN=1,seg=X)

2)B回复SYN_ACK包(SYN=1,ACK=1,seg=Y,ack number=X+1)

3)最后A向B传输消息(ACK=1,seg=X+1,ack number=Y+1)

从步骤3)开始A就可以携带应用层数据了。

TCP是可靠的数据传输协议,但在通过网络通信的过程中可能丢失数据。请通过ACK和SEQ说明TCP通过何种机制保证丢失数据的可靠传输。

SEQ是当前数据起始字节的序号,加入收到对方返回的ACK刚好是SEQ+数据大小(以字节为单位),则代表正确送达,可以继续发送后续数据包。反之,在计时器超时后进行重传。

TCP套接字中调用write和read函数时数据如何移动?结合I/O缓冲进行说明。

write函数调用瞬间,数据将移至输出缓冲;read函数调用瞬间,从输入缓冲读取数据。

对方主机的输入缓冲剩余50字节空间时,若本方主机通过write函数请求传输70 字节,请问TCP如何处理这种情况?

将70字节数据放入输出缓冲,然后发送50字节到对方主机,待对方主机的输入缓冲又有剩余时再发送后面的字节。

第2章示例tcp_server.c和tcp_client.c中,客户端接收服务器端传输的字符串后便退出。现更改程序,使服务器端和客户端各传递1次字符串。考虑到使用TCP协议,所以传递字符串前先以4字节整数型方式传递字符串长度。连接时服务器端和客户端数据传输格式如下。另外,不限制字符串传输顺序及种类,但须进行3次数据交换。

代码见附录。

0 0 0 6 H e l l o ?

|-- 字符串长度 --|------ 字符串数据 ------|

# gcc tri_server.c -o tserver

# ./tserver 9191

Connected client 1

Message from client: Hello?

Input message: Hi!

Message from client: This is Xiao.

Input message: I'm Yao.

Message from client: Nice to meet you!

Input message: Me, too.

# gcc tri_client.c -o tclient

# ./tclient 127.0.0.1 9191

Connected

Input message: Hello?

Message from server: Hi!

Input message: This is Xiao.

Message from server: I'm Yao.

Input message: Nice to meet you!

Message from server: Me, too.

创建收发文件的服务器端/客户端,实现顺序如下。

a. 客户端接受用户输入的传输文件名。

b. 客户端请求服务器端传输该文件名所指文件。

c. 如果指定文件存在,服务器端就将其发送给客户端;反之,则断开连接。

代码见附录。

# gcc file_server.c -o fserver

# ./fserver 9190

Connected client

# gcc file_client.c -o fclient

# ./fclient 127.0.0.1 9190

Connected

Input file name: exercise6

我的问题

把int存到char型数组中后发生了什么?

fgetc(stdin)的作用?

删除stdin中的"\n"字符,因为前面读取操作数的时候,最后有一个回车,他不能被当做运算符读进来。而前面读操作数之前为什么不fgetc一下呢?因为读取的是%d,它会自动找到整数来读取,忽略先导的空白符(指空格符、制表符、回车符)。但当读取的是%c的时候,scanf把缓冲区的第一个字符返回回去,不管是什么,所以如果不fgetc就会读取出“\n”。

seq与ack number的关系?

书中的seq与ack number有错误。以图5-4为例进行改正。

A B

| --- seq 1200 (100 bytes data) --> |

|

| --- seq 1300 (100 bytes data) --> |

|

C语言如果不初始化局部整型变量,里面的值是什么?

与编译器有关。对GCC来说,局部整型变量里的值是随机的。所以初始化是必需的。

为什么要用fgets读取用户输入,而不是scanf?

scanf遇空白符(空格、回车、制表符)即终止读取,无法一次性读取完整的一个句子。而fgets每次读取一行。

附录

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值