`

服务器和客户端的通信绘图

 
阅读更多

          还是先上图,现在的年轻人都不喜欢看文字,喜欢浏览图片,那就先把今天刚刚做完的一个东西先发出来,今天做完的“通信弹球”对于现在的我来说“现丑了”


                                                                图(a)
 


 

                                                         图(b)

图a是客户端的一个画板,图b是服务器端的一个画板,绘制在客户端的图像,通过一点点的协议和方法就能传到我们的服务器端,同时显示在服务器端的画板上,仔细看可能发现了(不仔细看也发现了)上面的图和下面的颜色有点不一样,这应该是延迟的原因,就像我们浏览网页时向服务器发送请求,要等半天才会有回应一样,就默认是这样的吧,在原谅的范围以内,图片也看了,下面开始今天的主题------通信。

         

        通信:通信,指人与人或人与自然之间通过某种行为或媒介进行的信息交流与传递,从广义上指需要信息的双方或多方在不违背各自意愿的情况下无论采用何种方法,使用何种媒质,将信息从某方准确安全传送到另方。(此处来自百度)

          上了这几节课,我对计算机上的通信的理解也就是:我有东西想给你,但是由于种种原因不能亲自给你,这可能有很多方面的原因,比如说是地域或者是不好意思,所以我要找一个东西来把我想给你的东西寄存在那里(在计算机上也就叫做服务器)如果你也想要知道给你的是什么东西!你就联系上它吧,但是,不是每个人平白无故的就能把我想给你的东西取走,就像寄快递的时候每个寄出的货物都有一个单号一样,服务器也是有号的要连接上他你就要知道他的单号是多少(也就是IP地址,和端口号),连接上后你就可以通过一点点的手段就可以把我的东西取走了。

          以上纯属个人见解,如有雷同不甚荣幸!

          怎么把东西放到寄存的那个地方呢?他又是怎么送到你的手上的呢?必须要有途径啊,就像快递通过海陆空送到各个地方一样,计算机中的信息也是一样,客户端要传到服务器里面,从服务器再传到客户端也是需要途径的,通信的“管道”,通过管道再加上一些通信的协议,就能实现数据的传输了,如下图所示:


 

                                                                               图(c)
 黑色的线就模拟了通信的通道,客户机和服务器连接,没个客户机对应着一套传输与接收的方法,进行数据的传输与共享。下面具体交代一下这几天学的东西。说说Java中是怎么实现服务器与客户端的。

 

在Java中要想编写网络通信,必须要用到java.net包下面的API,首先,我们来创建一个服务器,So easy  几行代码就可以搞定实例如下:

 

    Step1:

 

//创建一个服务器,并指定一个端口.
ServerSocket server = new ServerSocket(5678);

   PS:   端口号是什么?

               在网络技术中,端口(Port)大致有两种意思:一是物理意义上的端口,比如,ADSL Modem、集线器交换机路由器用 于连接其他网络设备的接口,如RJ-45端口、SC端口等等。二是逻辑意义上的端口,一般是指TCP/IP协议中的端口,端口号的范围从0到65535,比如用于浏览网页服务的80端口,用于FTP服务的21端口等等。我们这里将要介绍的就是逻辑意义上的端口。

             TCP与UDP段结构中端口地址都是16比特,可以有在0---65535范围内的端口号。对于这65536个端口号有以下的使用规定:

(1)端口号小于256的定义为常用端口,服务器一般都是通过常用端口号来识别的。任何TCP/IP实现所提供的服务都用1---1023之间的端口号,是由ICANN来管理的;
(2)客户端只需保证该端口号在本机上是惟一的就可以了。客户端口号因存在时间很短暂又称临时端口号;
(3)大多数TCP/IP实现给临时端口号分配1024---5000之间的端口号。大于5000的端口号是为其他服务器预留的
   所以,我们为我们自己写的服务器设置端口的时候应该避开前1024号端口.
Step2:服务器创建成功之后,就要让它进入等待状态,等待客户机的连接
/*客户机连接进入后,生成一个Socket对象,需要注意的是。调用了accept()方法
    *后,程序就会“阻塞”,就会等在这里,直到有一个客户机连接上来,这个方法才会返回,返回      * 的一个Socket对象就代表了服务器和客户机之间的连接,服务器和客户机上的通信就是在Socket     *对象client上进行
    /
    Socket client = server.accept();
 Step3:从Socket连接对象上调用方法得到输入输出流:
OutputStream out  = client.getOutputStream();
    InputStream  ins = client.getInputStream();
 Step4:使用输入输出流进行通信数据的读写,从输入流中读取从客户端发来的数据,在输出流写入数据   传送到客户端,这里需要注意的是不同类型的数据传输的机制是不同的入字符串就要先取得字符串的字节。
通过上面的四步一个简单的服务器就创建好了。真的不是很难。多练练那几行代码就能背下来了。
 
我们使用While()循环就能连接进来很多客户机
但是上面的服务器只能连接一个客户机,前一个退出后下一个才能接进来,原因就是调用accept()方法时卡卡住了,要等到第一个客户机执行完下面所有的事情之后,才能再次调用accept()方法,所以聪明的你应该想到了线程这个好东西,将进入服务器的每一个Socket对象交给一个线程去处理,接下来想要来接入的客户端就不需要等待了,直接开启下一个线程。然后用一个While(true)死循环来循环调用start()方法即可。
 
下面来说一下java中客户端的编写,一行代码,只要知道服务器的Ip地址和端口号示例如下:
//连接服务器
Socket socket = new Socket(ip,port);
 
但是要完成从服务器端的数据读写就要多写几行代码了
private DataInputStream dins;
    private DataOutputStream dous;	

         /**
	 * 连接服务器的方法
	 * @param ip 客户端的Ip地址
	 * @param port 服务器的端口号
	 * @return 成功返回true,失败返回false
	 */
	public boolean connServer(String ip,int port) {
		try {
			
			//连接服务器
			Socket socket = new Socket(ip,port);
			
			//得到输入输出流
			InputStream ins = socket.getInputStream();
			OutputStream ous = socket.getOutputStream();
			
			//读写通信数据
			dins = new DataInputStream(ins);
			dous = new DataOutputStream(ous);
			
		}catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}
        
    //从服务器上读取数据,以读取整形数据为例
	public void readFromServer() {
		while(true) {
			try {
				int x = dins.readInt();
				int y = dins.readInt();
			} catch (IOException e) {
				e.printStackTrace();
			}
		
		}
	}

    //向服务器发送数据以传输整形数据为例:
     public void sendXY(int x,int y) {
           try {
			dous.writeInt(x);
			dous.writeInt(y);
		} catch (Exception e) {
			e.printStackTrace();
		}
}

 

    最后把刚刚做完的一个小实验奉上,基于通信的”弹球“,主要的目的是练习服务器端界面编程和客户端的界面编程方法,还有数据的传递,熟练掌握后对后面一些基于通信的小游戏的开发应该有很大的帮助,自己做的游戏不再是单机版的了,也同时可以和小伙伴们一起玩耍。
 小实验一共为两个项目,一个是客户端,一个是服务器端,首先启动服务器,再启动客户端进行连接。


 
想要达到的效果就是小球能够实现在客户端和服务器端的同时弹动,代码很简单把主要的贴上。
客户端连接服务器并进行数据的传输的代码如上,下面贴上客户端控制小球运动和数据传输的代码:
package Tms.netjava.com;

import java.awt.Color;
import java.awt.Graphics;
/**
 * 客户端画小球的线程
 * 
 * @author sony
 * 
 */
public class DrawThread extends Thread {

	private Graphics g;
	private NetConn nc;
	//小球的初始坐标位置
	int x=200 ;
	int y=300 ;
       //设置小球的初试半径,后面碰到四周后,会越来越大,当大到一定程度时也可以缩小(没做)
	int rd = 20;
	//运动的速度为(1/36)秒每贞,看上去移动的比较平缓
	int speed = 1; 
	int red = 255;
	int green = 1;
	int blue = 255;
	//小球初始角度,是和正上方的夹角的大小
	private int angle=30;

	// 得到画布的高和宽

	public DrawThread(Graphics g) {
		this.g = g;
		nc = new NetConn();
		if (nc.connServer("192.168.56.1", 9090)) {
			// 读取数据

			nc.start();

		}
	}

	public void run() {

		while(true) {
			move();
			try {
				Thread.sleep(1000/36);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 小球运动的方法
	 */
	public void move() {
		
		//当小球碰到四周时,角度相应的变化,窗体的初始高和宽是(600,400)
		if(x<0||x>=600) {
			angle = 360 - angle;
			//碰到壁后改变小球半径
                         rd+=10;
		}
		if(y<0||y>=400) {
			angle = 180 - angle;
			rd+=10;
		}
		
		//测试代码
		System.out.println("x==="+x);
	    System.out.println("y==="+y);
	 
		double x11 = speed*Math.sin(angle*Math.PI/180);
	
		double y11 = speed*Math.cos(angle*Math.PI/180);
	
	   //因为计算的值为-1到1之间的小数,调用相应的向下floor()取整,和向上ceil取整方法
	   //并对计算值的正负进行判断,进行相应的处理,纸上画画就明白了。
		if(x11<0) {
			x += Math.floor(speed*Math.sin(angle*Math.PI/180));
		} else{
			x += Math.ceil(speed*Math.sin(angle*Math.PI/180));
		}
		
		if(y11<0) {
		
			y -=-Math.ceil(-y11);
		} else{
			y -=Math.ceil(speed*Math.cos(angle*Math.PI/180));
			
		}
		
		//给背景设置变化的颜色,也是清屏的颜色,变换的,好看一点
		
		red-=2;
		if(red<=0) {
			red=255;	
		}
		green+=5;
		if(green>=0) {
			green=255;	
		}
		blue-=7;
		if(blue<=0) {
			blue=255;
		}
		
		//将 数据传到服务器端
		nc.sendData(x, y,red,green,blue,rd);
		
		g.setColor(new Color(red,green,blue));
		g.fillRect(0, 0, 600, 400);
		//滚动的小球的颜色也随之改变
		g.setColor(new Color(green,blue,red));
		g.fillOval(x, y, rd, rd);
		
	}
}
   下面贴上服务器端的主要代码:
package tms.netjava.com;

import java.awt.Color;
import java.awt.Graphics;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class TmsServer extends Thread {

	// 创建画布
	private Graphics g;

	public TmsServer(Graphics g) {
		this.g = g;
	}

	public void run() {
		this.startServer(5678);
	}

	public void startServer(int port) {
		try {

			System.out.println("创建服务器在端口:" + port);
			// 创建服务器
			ServerSocket ss = new ServerSocket(port);
			// 等待客户机的链接
			Socket client = ss.accept();

			// 打印客户机的地址
			System.out.println("连接进来一个客户机,客户机的地址为"
					+ client.getRemoteSocketAddress());

			// 取得输入输出流
			InputStream ins = client.getInputStream();
			OutputStream ous = client.getOutputStream();

			// 读写通信数据
			DataInputStream dins = new DataInputStream(ins);
			DataOutputStream dous = new       DataOutputStream(ous);

			// 从客户端得到发来的数据
			while (true) {
				int x = dins.readInt();
				int y = dins.readInt();
				int red = dins.readInt();
				int green = dins.readInt();
				int blue = dins.readInt();
				int rd = dins.readInt();

				// 清屏
				g.setColor(new Color(red, green, blue));
				g.fill3DRect(5, 5, 600, 400, false);

				// 利用得到坐标将指定的图形画出来
				g.setColor(new Color(green, blue, red));
				g.fillOval(x, y, rd, rd);
			}

		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
  
实现的效果也就是小球会在客户端的画布和服务器端的画布上变换着颜色弹动,越弹越大。
效果如下:
 


 

 
撞了几次墙之后:


 

 


 
 

 

最后总结:踏踏实实,一步一个脚印的慢慢的踩。即使路上布满荆棘,也要勇敢走下去,不管结果如何,吃多了还是会长胖。
 

 

 

 

 

 

 

 

 

  • 大小: 30.1 KB
  • 大小: 27.3 KB
  • 大小: 100.4 KB
  • 大小: 47.5 KB
  • 大小: 23.7 KB
  • 大小: 22.1 KB
  • 大小: 22.4 KB
  • 大小: 31.6 KB
  • 大小: 34.7 KB
  • 大小: 33.4 KB
3
3
分享到:
评论
1 楼 freezingsky 2014-03-20  
动手能力挺好!

相关推荐

    VC 通过UDP协议发送和接受绘图数据.rar

    VC 通过UDP协议发送和接受绘图数据,是一个网络文件传输的通信实例,程序为了演示方便,分别编写了客户端和服务端,在客户端中绘图,并可将绘图数据发送给服务器端,使用了UDP协议构建的传输引擎。

    giraffeboi:使用 influxdata 的 giraffe 库

    客户端是用 React 和 JavaScript 编写的,并使用 Fetch 与服务器通信。 src/server和src/client是服务器和客户端的代码位置。 启动服务器 INFLUX_URL=...

    远程绘制图像

    自己在学校编的 远程绘图软件,通过建立客户端、服务器端,可以让让两台计算机上的程序进行通信,实现远程绘图

    一款非常不错的电子白板工具源代码

    JAVA开发的电子白板源代码....服务器端和客户端程序都在压缩文件中,在局域网内测试成功,服务器与多客户端之间通过SOCKET机制进行通信,支持多人同时绘图,写字聊天等功能.代码结构非常清晰,易懂,功能还是比较强大的!

    socket.io-draw:使用https进行聊天绘图的共享板

    客户端服务器该“应用程序”使用库(具有非常好的API和文档)来允许用户通过服务器进行通信,该服务器仅相互广播消息。 在此项目中同时设置了服务器(Node.js)和客户端(Browser JS)。 只需运行npm install && npm...

    cartography-map:制图地图应用程序的回购

    Node-Express服务器:它服务于地图网站,接收和存储来自用户的旅程数据,并将这些数据中继到显示应用程序 一个显示应用程序(使用Processing 3.3.7构建):它从服务器接收数据,将其显示在地图上,并通过Siphon与...

    canvas:使用WebSocket在服务器浏览器中的Web浏览器中HTML 2D画布上绘制

    反过来,客户端将键盘,鼠标和触摸事件发送到服务器。 该模块不需要特定于操作系统的后端或Cgo绑定。 它不使用WebAssembly,这意味着Go代码在服务器端而不是浏览器中运行。 客户-服务器设计意味着可以将画布显示在...

    citect7.0 用户指南

    单机系统、分布式 I/O 系统、客户端-服务器系统、冗余服务器系统 集群式控制系统、冗余和分布式控制系统、负载分担系统 使用 Vijeo Citect Chapter: 8 规划工程 工厂的物理布局、操作要求、工程设计 构建工程、部署...

    配电网通信网络全过程可视化管控平台研究

    文中基于服务器硬件平台和Visual Studio、SQL Server的软件平台,开发了具备图形直观显示与数据处理分析等功能的客户端-服务器可视化管理系统。本系统的第一个贡献点是提出了潮流逆向搜索算法,能够分析配电网中电源...

    liveboard:远程共享绘图应用程序的 Java 代码

    它使用客户端-服务器架构将消息从一个客户端传递到另一个客户端。 GUI 是使用 Swing 库设计的,通信是通过套接字完成的。 程序假设连接是通过localhost完成的,所以要运行程序首先需要运行Servidor类初始化服务器...

    Stipple.jl:使用纯Julia的交互式UI应用程序的React式UI库

    点画使用高性能的MVVM体系结构,该体系结构自动同步状态的两种方式(服务器-&gt;客户端和客户端-&gt;服务器),仅通过网络发送JSON数据。 Stipple软件包提供了基本的通信层,通过React组件扩展了GenieHTML API。 点画...

    30天学通C#项目案例开发源码(上) 孔琳俊

    3.2.4 即时通信客户端系统预览 104 3.2.5 服务器端系统预览 106 3.3 开发前的准备工作 106 3.3.1 模块设计 107 3.3.2 系统流程描述 108 3.4 即时通信服务类库实现 109 3.4.1 类库项目结构 109 3.4.2 使用...

    WhiteBoard:共享白板是互联网协作的一种形式,我们开发了一种分布式白板,供个人根据套接字方案从不同主机进行可视化访问和通信。 首先,报告介绍了远程应用的发展情况。 然后在第二部分,它说明了

    白板共享白板是互联网协作的一种形式,我们开发了一种分布式白板,供个人根据套接字方案从不同主机进行可视化访问和通信。 首先,报告介绍了远程应用的发展情况。 然后在第二部分,它说明了概要动机该项目的目的是...

    qt必备学习手册初级

    6 绘图和绘图设备 63 6.1 QPainter 63 6.2 绘图设备 65 6.2.1 QPixmap、QBitmap、QImage 66 6.2.2 QPicture 69 7 文件系统 70 7.1 基本文件操作 71 7.2 二进制文件读写 73 7.3 文本文件读写 75 8 Socket通信 76 8.1 ...

    vc++ 应用源码包_1

    它包括客户端和服务端,客户端软件主要作用是监测本主机的活动,并将监测到的信息定时发送给服务器。服务器可以将收集到的信息以柱状图和文件列表以及其他方式呈现给用户,以便用户对局域网内的主机进行监测和管理。...

    vc++ 应用源码包_6

    它包括客户端和服务端,客户端软件主要作用是监测本主机的活动,并将监测到的信息定时发送给服务器。服务器可以将收集到的信息以柱状图和文件列表以及其他方式呈现给用户,以便用户对局域网内的主机进行监测和管理。...

    vc++ 应用源码包_2

    它包括客户端和服务端,客户端软件主要作用是监测本主机的活动,并将监测到的信息定时发送给服务器。服务器可以将收集到的信息以柱状图和文件列表以及其他方式呈现给用户,以便用户对局域网内的主机进行监测和管理。...

    vc++ 应用源码包_5

    它包括客户端和服务端,客户端软件主要作用是监测本主机的活动,并将监测到的信息定时发送给服务器。服务器可以将收集到的信息以柱状图和文件列表以及其他方式呈现给用户,以便用户对局域网内的主机进行监测和管理。...

Global site tag (gtag.js) - Google Analytics