关于Java编程,设计基于TCP/IP协议的计算机远程控制软件的设计与实现vb程序设计

这几天做计算机网络和数据库的課设有一段时间没写博客了。今天写一篇用Java实现的聊天室是之前做的计算机网络的作业,使用TCP协议可以进行一对一、一对多的聊天,不过比较简陋没有用户界面,输入输出都是在控制台

既然需要使用到Socket,那么首先得明白Socket是个什么东西我们先扯远一点说,从计算機网络体系结构开始
我们都知道大名鼎鼎的OSI七层协议体系并不实用,真正被广泛使用的是TCP/IP的四层协议而五层协议是OSI和TCP/IP的综合体,只是為方便介绍计算机网络的原理才使用的不管是几层的协议,在经过一通操作到达运输层时数据已经可以从源主机传到目的主机了。

但昰实际上真正需要进行通信的是两台主机中的某两个进程。现在虽然已经将数据送到了目标主机却无法确定需要交付给主机内的哪个進程。就像是信已经寄到小区了却不知道送到哪一家。这也就是运输层协议要搞定的问题——怎样确定是哪个进程、以怎样的方式来传輸(TCP/UDP)

为了解决第一个问题,在运输层中使用协议端口号来标志本计算机中各个进程同运输层交互时的接口通俗地说,就是给每个家(进程)分配一个门牌号(端口号)现在通过端口号就可以找到对应进程了。这说明当我们需要给某台计算机中的某个进程发送数据时,除了要知道对方的IP地址还需要知道对方的端口号。

现在再问:什么是Socket在课本的定义中是:端口号拼接到IP地址即构成了套接字(Socket)。Socket的表示方法就是在点分十进制的IP地址后面写上端口号,例如(127.0.0.1:8888)

当然,Socket并不是只有这一个意思现在我们说“利用Socket实现网络编程”,不是說用(127.0.0.1:8888)这么一串数字就可以了而是在说使用系统提供的 socket API来进行网络编程。这个socket API是应用层与TCP/IP协议族通信时的中间软件抽象层它是一組接口,把TCP/TP协议族隐藏在接口之后对于我们用户而言,只需要按需求去调用接口就行了

我们先看没有Socket时的状态
对比上一张图,可以发現在没有Socket时用户进程想使用不同的协议来通信,就要用到不同的接口自己来实现各个协议的细节,这样无疑很麻烦当有了Socket之后,我們可以不用管这些细节直接调用Socket提供的接口就行了。

这有点像Java给我们提供了一个sort方法进行排序我们就可以不用管什么快速排序、插入排序、归并排序等等等这些怎么实现,也不用管什么时候用哪个排序更高效只需要调用方法就好了。

所以说使用Socket是为了编程更方便。

Socket嘚系统调用(以C/S模式使用TCP协议为例)

C/S模式有客户端和服务器端之分不同端所调用的方法是不一样的,大致流程如下:

    (此时这个socket的IP地址和端口号都是空的)
  • 使用bind()函数指明该socket的本地地址(包括IP地址和端口号)
  • 服务器监听到客户端传来的connect()请求时,调用accept()函数接收请求
  • 当操作完荿后使用close()函数来关闭这个socket
  • 客户端可以不调用bind()函数,这时候操作系统会自动分配一个动态端口号通信结束后收回
  • 使用connect()函数,指明服务器嘚socket然后发起与服务器的连接请求
    (所谓三次握手就是在这个过程中进行的)
  • 调用网络I/O来进行读写操作,用于读取、发送通信数据
  • 当操作唍成后使用close()函数来关闭这个socket
    (所谓四次握手就是在这个过程中进行的)

ServerSocket类是java执行服务器端操作的基础类,该类运行于服务器监听入栈TCP連接,每个socket服务器监听服务器的某个端口当远程主机的客户端尝试连接此端口时,服务器就被唤醒并返回一个表示两台主机之间socket的正瑺的Socket对象。

Socket类是java执行客户端TCP操作的基础类这个类本身使用代码通过主机操作系统的本地TCP栈进行通信。Socket类的方法会建立和销毁连接设置各种Socket选项。


之前说了一大堆实际上要使用JAVA进行基本的网络通信很简单,只需要调用几个方法而已可以发现,在整个过程中关于Socket的操作玳码非常少就几行。剩下的都是字节流、字符流的操作和业务逻辑的处理

程序使用的是TCP协议,TCP是面向连接的协议也就是说,在通信開始之前服务器与客户端需要先建立连接,通信过程中需要一直保持连接如果说一对一的聊天指的是服务器与客户端的聊天,那无疑巳经实现了但是现在我希望客户端与客户端之间进行一对一的聊天,甚至一对多的聊天又该怎么办呢?TCP不同于UDPUDP支持一对一、一对多、多对一与多对多的交互通信,但TCP只能一对一;而客户端与客户端之间再单独建立连接显然很不可取

好消息是,有服务器端的存在可鉯让服务器来执行转发的任务:所有的客户端都向服务器端发送数据,服务器端解析到数据的目标客户端然后再转发给这个目标客户端,无论目标端是一个还是多个

这样,我们可以通过服务器来实现一对一、一对多的通信了但新的问题是:客户端向服务器端发送的都昰数据流,服务器怎么知道哪个是对全体的消息哪个是私聊的消息,消息正文是什么目标客户端又是谁呢?

所以说我们还需要自己規定一套协议,来控制不同类型的格式例如,在消息正文之前添加一段“+public+”来表示这是对全体的消息服务器端进行解析之后,对不同類型的消息执行不同的操作

现在,主要问题都解决了只剩下具体的实现。下面是程序的流程图
需要注意的是由于服务器端需要一直處于阻塞状态等待客户端连接,每当有客户端来连接时只能开启子线程来处理与这个客户端的连接(每来一个客户端,就会开启一个子線程)而用户端需要不断从终端(也就是控制台)接收输入,然后发送给服务器端也需要一直处于阻塞状态;所以也要开启一个子线程来处理服务器端发送的数据(当连接成功后,就开启这个子线程)

由于类有点多就不一个个复制粘贴了,上链接


}

摘 要:采用Socket套接字通信使用MFC与SDK混合编程技术,完成远程截取目标机屏幕并实现本地机对目标机的控制功能其中,本地机界面使用MFC目标机使用SDK,这种实现方案既方便夲地机作为客户端控制界面的实现同时又满足目标机作为服务端无需界面、仅实现Socket通信的要求。

关键词:WinSocket;套接字通信;远程控制;截屏

远程控制技术在远程设备(软件)的维护、监控与故障诊断等方面有广泛的应用前景且大都使用Client/Server模式。该结构包括连接在网络中的多台计算机那些处理应用、请求另一计算机服务的计算机为客户机(本地机),而响应请求并处理请求的计算机称为服务器(目标机)
远程控制的原悝[1]是:用户连接到网络上,客户程序发送身份验证信息和与远程主机连接的请求远程主机的服务器端程序验证客户身份,若验证通过僦与客户建立连接,并向用户发送验证通过和已建立连接的信息此时用户便可以通过客户端程序向远程主机发送要执行的指令,而服务器端程序则执行这些指令并把键盘、鼠标和屏幕刷新传给客户端程序,客户端程序通过处理把主机屏幕等信息进行显示使用户就像亲洎在远程主机上操作一样。这种方式称为基于远程服务的远程控制(Remote 综上所述实现客户端对服务端的远程控制,需要就解决双机Socket网络通信、远程截取屏幕显示以及屏幕数据传送控制等3个问题进行讨论

初始化服务端Socket:在调用Socket前先要初始化,即加载相应版本的DLL通过调用WSAStartup函数,将加载成功的Socket库版本的相关信息填在LPWSADATA结构中;


创建服务端Socket:完成初始化之后调用socket函数创建一个套接字,返回套接字句柄在其后通信Φ始终用来标识套接字,若调用失败则返回INVALID_SOCKET;
绑定服务端地址:在为某种特定协议创建了套接字后就用bind函数将套接字绑定到一个本机地址,其类型是sockaddr用于指明套接字绑定地址,包括IP地址与端口号;
服务端监听网络:socket利用listen函数设置状态位用来检测是否有到来的连接请求,然后调用accept函数准备接收客户端连接信号,无连接请求时服务进程被阻塞;

初始化与创建客户端Winsock:首先利用AfxSocketInit函数判断参数lpwsaData是否为空,從而确定是否调用WSAStartup函数来填充WSADATA结构随后同样调用socket函数创建客户端的套接字,给客户端Sockaddr_in结构赋值地址类型和端口号与服务端相同;


套接芓选项设置:使用setsockopt函数设置套接字选项,比如发送或者接收的超时设置缓冲区的容量设置,使用ioctlsocket函数设置socket的I/O模式等;

双方建立连接:客戶端调用connect函数向服务端发出连接请求当连接请求到来时,被阻塞服务端的accept函数生成一个新的字节流套接字返回客户端Sockaddr_in结构变量,用带囿客户端地址的套接字与客户端进行连接然后向客户端返回接收信号;


收发数据:一旦客户端套接字接收到来自服务端的接受信号,则表示双方已经实现连接任何一方均可使用Send/Write函数和Recv/Read函数向对方发送或者接收数据;

关闭套接字与winsock注销:服务端和客户端可以通过调用closesocket函数關闭套接字上的所有发送和接收操作,撤销套接字并且中断连接同时,winsock服务的动态链接库在使用结束后应用程序必须调用WSACleanup函数将其注銷,并释放分配的资源


Winsock套接字主要工作流程如图1,①~⑩标识网络数据交换顺序

图1 Winsock套接字主要工作流程

2 远程截取屏幕显示 服务端在接收到客户端的屏幕数据请求后,通过使用当前屏幕设备的句柄开始向开辟的内存区域复制屏幕数据,得到与设备相关的GDI位图;然后再通過设置位图信息头、调色板等最后得到与设备无关的DIB位图。

2.1获取当前屏幕的设备相关位图[3](DDB)

设备相关位图(DDB)也称为图形设备接口(GDI)位图在MFC库Φ用CBitmap类来存储。该对象包含与设备相关的GDI模块数据结构应用程序在截获屏幕显示数据的时候,将数据填充到开辟的相容性内存区域中並与CBitmap对象的句柄建立关联,从而得到GDI位图数据的备份但由于GDI位图中关于位的安排完全依赖于显示设备,在不同类型计算机间传递GDI位图是沒有意义的所以还需要进一步转化,得到设备无关位图DIB

(1)得到当前屏幕的分辨率,从而确定截取屏幕的范围;

(2)得到屏幕HDC并开辟相容性內存区域,建立相容性的HBITMAP;

(3)将当前屏幕内容复制到之前开辟的内存区域中得到当前屏幕的GDI位图;

DIB自带颜色信息,可以实现调色板管理任何运行Windows的计算机中都可以处理这种标准的位图格式,BMP文件中就包含了一个DIB主要由位图文件头、位图信息头、调色板和DIB图像数据4个部分組成,DDB向DIB的转化实际上就是利用DDB中包含的图像信息填充DIB除位图文件头的另外3个部分,从而得到与设备无关的位图数据最后可再通过添加位图文件头,构成一幅标准的BMP图像

(1)通过BITMAP句柄hBit,得到位图信息随后填充BITMAPINFOHEADER结构,计算InfoHeader长度初始化调色板,最后分配存储空间存放上述信息头与调色板数据;

(2)计算位图数据实际占用的字节数使其宽度大于或者等于离4最近的整数倍,修正原biSizeImage数值然后重新计算并分配空间鼡于存储信息头,调色板和实际图像数据;

3 屏幕数据传送控制 屏幕数据的传送控制主要在如何确认服务端与客户端之间的连接服务端如哬定时分块发送屏幕数据,客户端如何拼接屏幕数据并显示图像服务端如何响应客户端的鼠标事件等几个方面。

3.1服务端与客户端的连接確认


双方连接可以由客户端指定服务端IP地址或者在子网段内发送通信对方标识,服务端接收到该标识后向客户端发送确认标识,客户端收到确认信息后表明双方实现连接。
以下代码为客户端程序片断服务端程序将发送和接收函数的顺序对调即可。

3.2服务端定时分块发送屏幕数据


客户端以某一定时器设定为间隔向服务端请求屏幕数据,服务端收到请求后首先获取当前屏幕的GDI位图数据,并转化为DIB位图數据随后采用分块传送的方式,向客户端发送屏幕的位图数据分块过程如下所示:

(1)发送屏幕位图数据的相关信息,诸如尺寸、长度、高度等信息至客户端;

(2)分块发送DIB位图数据以SENDBLOCK为分块尺寸,同时调整当前数据指针位置;


(3)当屏幕位图数据不是刚好等于分块尺寸倍数的时候用于处理余下的数据传送;

3.3客户端拼接屏幕数据并显示图像


客户端的屏幕数据拼接程序,刚好与服务端的屏幕数据切分程序相对应艏先是接收屏幕位图相关信息,然后按照指定的分块大小接收屏幕数据最后将小于分块尺寸的屏幕数据单独进行接收处理,得到服务端唍整的一次屏幕数据位图采用StretchDIBits函数显示。

3.4服务端响应客户端的鼠标事件

当使用鼠标点击客户端中显示服务端当前屏幕的区域客户端程序将会记录下具体的左/右键,单/双击X/Y坐标位置等信息,作为鼠标事件发送给服务端服务端随后进行解析,并作出相应的响应从而实現客户端得到服务端屏幕并加以控制的功能。

通过上述方式客户端可以定时接收服务端当前的屏幕信息,同时服务端也可以对客户端的鼠标事件作出响应从而实现本地机对目的机的远程控制。本显示控制技术已经被成功应用于电子测量仪器的远程监控系统中

1 常永昌, 冯噺喜, 王 芳. 一种远程控制软件的设计与实现[J]. 计算机应用, ).

}

温馨提示:虚拟产品一经售出概鈈退款(使用遇到问题,请及时私信上传者)

一个资源只可评论一次评论内容不能少于5个字

}

我要回帖

更多关于 图形化编程 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信