【C/C++套接字编程】TCP通信实验

一、实验目的:

通过本实验使学员了解和掌握编写基于TCP协议的网络应用程序。任务是开发一个基于TCP Socket API的网络聊天程序。

二、实验内容简要描述

用所学的TCP Socket API知识来开发基于TCP协议的网络。通过编程实现服务端和客户端的信息通信。TCP协议建立交互的流程如下图所示。通过编写C/C++程序,调用windows提供的Socket API,模拟下述流程,建立客户端与服务端的远程TCP通信。使得彼此双方能够接收彼此信息、发送信息。

【C/C++套接字编程】TCP通信实验_第1张图片

三、实验步骤与结果分析

基于TCP协议的面向客户/服务器的工作流程是:

  • 服务器端:

Ⅰ 服务器首先启动,调用 socket( )创建套接字;

Ⅱ 然后调用bind( )指定服务器socket地址(IP地址+端口号);

Ⅲ 再调用listen( )让服务器做好侦听准备,并规定好请求队列的长度,然后服务器进入阻塞状态,等待客户的连接请求;

Ⅳ 最后通过accept( )来接收连接请求,并获得客户的socket地址。

  •  客户端

Ⅰ 客户在创建套接字并指定客户 socket地址

Ⅱ 然后就调用connect( )和服务器建立连接。

Ⅲ 一旦连接建立成功,客户和服务器之间就可以通过调用read( )和write( )来接收和发送数据

Ⅳ 一旦数据传输结束,服务器和客户通过调用close( )来关 闭套接字。

服务端:

  1. 启动,调用socket()创建套接字

【C/C++套接字编程】TCP通信实验_第2张图片

  1. 在创建套接字之后,套接字作为网络端口的抽象,需要与具体的IP/端口进行绑定,之后我们才可以通过套接字这一层抽象简便地实现通信。我们先设置好地址,然后调用bind()函数将套接字与地址绑定。

【C/C++套接字编程】TCP通信实验_第3张图片

这里与本地地20000端口进行绑定。在实际的两台主机之间通信时,将回环地址修改为自己的IPv4地址即可(如果套接字参数选择IPv6,则相应的使用IPv6地址);端口号的选择只需要确保和已有的端口不冲突即可。

  1. TCP协议是面向连接的通信协议,因此首先要确保服务端与用户端的联系紧密,尔后再进行稳定可靠的通信。建立联系的过程,需要服务端进行监听,等待用户端的连接、通信请求。这个监听的过程,通过listen()、阻塞来实现。

【C/C++套接字编程】TCP通信实验_第4张图片

  1. 当服务端在监听时收到了来自客户端的通信请求(连接),就通过accept()获取客户端的Socket地址,进而建立TCP联系。然后就可以通过套接字与客户端进行交互。

【C/C++套接字编程】TCP通信实验_第5张图片

  1. 交互过程分为接收发送两个阶段,由于程序的单线程下,接收和发送均存在阻塞状态,因此只能实现接受和发送的交替轮流通信。对于交互过程,我将它封装在interactive()函数中,通过传入客户端的套接字信息,实现本机(服务端)与客户端的信息交流。实际上,对于交互过程的封装,是为了之后进一步的“多线程”互联所作的准备;多线程实现通信将放在本节内容最后进行阐述。

【C/C++套接字编程】TCP通信实验_第6张图片

可以注意到其中有一些函数如print_time()等,是为了控制界面的打印。由于这些细节与TCP协议实现并无太大关联,故具体这些控制函数将放在后面进行“结论”的收获部分进行汇报。

  1. 最后,当通信完毕,就通过close来关闭套接字、断开连接。

        客户端:

  1. TCP协议不同于UDP协议,是更为可靠的,因此客户端和服务端一样,都需要建立套接字对本机端口进行抽象。客户端也通过socket()函数。

【C/C++套接字编程】TCP通信实验_第7张图片

  1. 然后,根据服务端的地址和端口数据,通过connect()主动连接服务端程序。

【C/C++套接字编程】TCP通信实验_第8张图片

  1. 连接建立成功之后,便可以和服务端进行通信交互,方式和服务端相同,只不过约定首先发送信息。

【C/C++套接字编程】TCP通信实验_第9张图片

  1. 同样的,在通信完毕之后,断开连接,与服务端方式相同,这里就不赘述。

基于以上连接策略实现的简易TCP通信结果如下:

【C/C++套接字编程】TCP通信实验_第10张图片

【C/C++套接字编程】TCP通信实验_第11张图片

可见,达成了TCP简易通信的基本目标。

        基于多线程的TCP通信服务

   由于TCP自身的特性以及收发信息的阻塞状态,单个线程无法实现多主机互联。因此这里尝试采用服务端多线程的方式,实现多台客户端与服务端交互而客户端之间互相屏蔽的TCP交互功能。

        相对于上述服务端代码,主要的区别在于,主线程循环接收连接,子线程进行服务端与客户端的交互。

【C/C++套接字编程】TCP通信实验_第12张图片

【C/C++套接字编程】TCP通信实验_第13张图片

        最终实现效果如下:

【C/C++套接字编程】TCP通信实验_第14张图片

【C/C++套接字编程】TCP通信实验_第15张图片

四、结论

此次实验,让我更加了解了TCP协议的过程,同时也初步掌握了C++ Socket编程的基础技能,更让我在实际的应用中,尝试使用多线程、利用控制字符美化交互环境等等,受益匪浅。

此次实验完成了基本的TCP通信交互任务,还扩展了多台客户端与服务端交互的实现。接下来我将尝试加入可视化界面,同时更加优化字符打印的交互界面。

对于控制打印的函数,自己通过摸索,也有了很大的收获:

打印时间

【C/C++套接字编程】TCP通信实验_第16张图片

         通过套接字获取地址

【C/C++套接字编程】TCP通信实验_第17张图片

                回退到黑窗口上一行并覆写

【C/C++套接字编程】TCP通信实验_第18张图片

你可能感兴趣的:(套接字编程,计算机网络,tcp/ip,c语言,c++,网络,套接字)