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

  • 博客分类:
  • Java基础

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

图(a)

图(b)

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

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

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

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

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

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

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

Step1:

Java代码  
  1. //创建一个服务器,并指定一个端口.
//创建一个服务器,并指定一个端口.
Java代码  
  1. ServerSocket server = new ServerSocket(5678);
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:服务器创建成功之后,就要让它进入等待状态,等待客户机的连接
Java代码  
  1. /*客户机连接进入后,生成一个Socket对象,需要注意的是。调用了accept()方法
  2. *后,程序就会“阻塞”,就会等在这里,直到有一个客户机连接上来,这个方法才会返回,返回      * 的一个Socket对象就代表了服务器和客户机之间的连接,服务器和客户机上的通信就是在Socket     *对象client上进行
  3. /
  4. Socket client = server.accept();
/*客户机连接进入后,生成一个Socket对象,需要注意的是。调用了accept()方法
*后,程序就会“阻塞”,就会等在这里,直到有一个客户机连接上来,这个方法才会返回,返回      * 的一个Socket对象就代表了服务器和客户机之间的连接,服务器和客户机上的通信就是在Socket     *对象client上进行
/
Socket client = server.accept();

Step3:从Socket连接对象上调用方法得到输入输出流:

Java代码  
  1. OutputStream out  = client.getOutputStream();
  2. InputStream  ins = client.getInputStream();
OutputStream out  = client.getOutputStream();
InputStream  ins = client.getInputStream();

Step4:使用输入输出流进行通信数据的读写,从输入流中读取从客户端发来的数据,在输出流写入数据   传送到客户端,这里需要注意的是不同类型的数据传输的机制是不同的入字符串就要先取得字符串的字节。

通过上面的四步一个简单的服务器就创建好了。真的不是很难。多练练那几行代码就能背下来了。
我们使用While()循环就能连接进来很多客户机
但是上面的服务器只能连接一个客户机,前一个退出后下一个才能接进来,原因就是调用accept()方法时卡卡住了,要等到第一个客户机执行完下面所有的事情之后,才能再次调用accept()方法,所以聪明的你应该想到了线程这个好东西,将进入服务器的每一个Socket对象交给一个线程去处理,接下来想要来接入的客户端就不需要等待了,直接开启下一个线程。然后用一个While(true)死循环来循环调用start()方法即可。
下面来说一下java中客户端的编写,一行代码,只要知道服务器的Ip地址和端口号示例如下:
Java代码  
  1. //连接服务器
  2. Socket socket = new Socket(ip,port);
//连接服务器
Socket socket = new Socket(ip,port);

但是要完成从服务器端的数据读写就要多写几行代码了
Java代码  
  1. private DataInputStream dins;
  2. private DataOutputStream dous;
  3. /**
  4. * 连接服务器的方法
  5. * @param ip 客户端的Ip地址
  6. * @param port 服务器的端口号
  7. * @return 成功返回true,失败返回false
  8. */
  9. public boolean connServer(String ip,int port) {
  10. try {
  11. //连接服务器
  12. Socket socket = new Socket(ip,port);
  13. //得到输入输出流
  14. InputStream ins = socket.getInputStream();
  15. OutputStream ous = socket.getOutputStream();
  16. //读写通信数据
  17. dins = new DataInputStream(ins);
  18. dous = new DataOutputStream(ous);
  19. }catch (Exception e) {
  20. e.printStackTrace();
  21. }
  22. return false;
  23. }
  24. //从服务器上读取数据,以读取整形数据为例
  25. public void readFromServer() {
  26. while(true) {
  27. try {
  28. int x = dins.readInt();
  29. int y = dins.readInt();
  30. } catch (IOException e) {
  31. e.printStackTrace();
  32. }
  33. }
  34. }
  35. //向服务器发送数据以传输整形数据为例:
  36. public void sendXY(int x,int y) {
  37. try {
  38. dous.writeInt(x);
  39. dous.writeInt(y);
  40. } catch (Exception e) {
  41. e.printStackTrace();
  42. }
  43. }
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();
}
}

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


 
想要达到的效果就是小球能够实现在客户端和服务器端的同时弹动,代码很简单把主要的贴上。
客户端连接服务器并进行数据的传输的代码如上,下面贴上客户端控制小球运动和数据传输的代码:
Java代码  
  1. package Tms.netjava.com;
  2. import java.awt.Color;
  3. import java.awt.Graphics;
  4. /**
  5. * 客户端画小球的线程
  6. *
  7. * @author sony
  8. *
  9. */
  10. public class DrawThread extends Thread {
  11. private Graphics g;
  12. private NetConn nc;
  13. //小球的初始坐标位置
  14. int x=200 ;
  15. int y=300 ;
  16. //设置小球的初试半径,后面碰到四周后,会越来越大,当大到一定程度时也可以缩小(没做)
  17. int rd = 20;
  18. //运动的速度为(1/36)秒每贞,看上去移动的比较平缓
  19. int speed = 1;
  20. int red = 255;
  21. int green = 1;
  22. int blue = 255;
  23. //小球初始角度,是和正上方的夹角的大小
  24. private int angle=30;
  25. // 得到画布的高和宽
  26. public DrawThread(Graphics g) {
  27. this.g = g;
  28. nc = new NetConn();
  29. if (nc.connServer("192.168.56.1", 9090)) {
  30. // 读取数据
  31. nc.start();
  32. }
  33. }
  34. public void run() {
  35. while(true) {
  36. move();
  37. try {
  38. Thread.sleep(1000/36);
  39. } catch (Exception e) {
  40. e.printStackTrace();
  41. }
  42. }
  43. }
  44. /**
  45. * 小球运动的方法
  46. */
  47. public void move() {
  48. //当小球碰到四周时,角度相应的变化,窗体的初始高和宽是(600,400)
  49. if(x<0||x>=600) {
  50. angle = 360 - angle;
  51. //碰到壁后改变小球半径
  52. rd+=10;
  53. }
  54. if(y<0||y>=400) {
  55. angle = 180 - angle;
  56. rd+=10;
  57. }
  58. //测试代码
  59. System.out.println("x==="+x);
  60. System.out.println("y==="+y);
  61. double x11 = speed*Math.sin(angle*Math.PI/180);
  62. double y11 = speed*Math.cos(angle*Math.PI/180);
  63. //因为计算的值为-1到1之间的小数,调用相应的向下floor()取整,和向上ceil取整方法
  64. //并对计算值的正负进行判断,进行相应的处理,纸上画画就明白了。
  65. if(x11<0) {
  66. x += Math.floor(speed*Math.sin(angle*Math.PI/180));
  67. } else{
  68. x += Math.ceil(speed*Math.sin(angle*Math.PI/180));
  69. }
  70. if(y11<0) {
  71. y -=-Math.ceil(-y11);
  72. } else{
  73. y -=Math.ceil(speed*Math.cos(angle*Math.PI/180));
  74. }
  75. //给背景设置变化的颜色,也是清屏的颜色,变换的,好看一点
  76. red-=2;
  77. if(red<=0) {
  78. red=255;
  79. }
  80. green+=5;
  81. if(green>=0) {
  82. green=255;
  83. }
  84. blue-=7;
  85. if(blue<=0) {
  86. blue=255;
  87. }
  88. //将 数据传到服务器端
  89. nc.sendData(x, y,red,green,blue,rd);
  90. g.setColor(new Color(red,green,blue));
  91. g.fillRect(0, 0, 600, 400);
  92. //滚动的小球的颜色也随之改变
  93. g.setColor(new Color(green,blue,red));
  94. g.fillOval(x, y, rd, rd);
  95. }
  96. }
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);
}
}

下面贴上服务器端的主要代码:

Java代码  
  1. package tms.netjava.com;
  2. import java.awt.Color;
  3. import java.awt.Graphics;
  4. import java.io.DataInputStream;
  5. import java.io.DataOutputStream;
  6. import java.io.InputStream;
  7. import java.io.OutputStream;
  8. import java.net.ServerSocket;
  9. import java.net.Socket;
  10. public class TmsServer extends Thread {
  11. // 创建画布
  12. private Graphics g;
  13. public TmsServer(Graphics g) {
  14. this.g = g;
  15. }
  16. public void run() {
  17. this.startServer(5678);
  18. }
  19. public void startServer(int port) {
  20. try {
  21. System.out.println("创建服务器在端口:" + port);
  22. // 创建服务器
  23. ServerSocket ss = new ServerSocket(port);
  24. // 等待客户机的链接
  25. Socket client = ss.accept();
  26. // 打印客户机的地址
  27. System.out.println("连接进来一个客户机,客户机的地址为"
  28. + client.getRemoteSocketAddress());
  29. // 取得输入输出流
  30. InputStream ins = client.getInputStream();
  31. OutputStream ous = client.getOutputStream();
  32. // 读写通信数据
  33. DataInputStream dins = new DataInputStream(ins);
  34. DataOutputStream dous = new       DataOutputStream(ous);
  35. // 从客户端得到发来的数据
  36. while (true) {
  37. int x = dins.readInt();
  38. int y = dins.readInt();
  39. int red = dins.readInt();
  40. int green = dins.readInt();
  41. int blue = dins.readInt();
  42. int rd = dins.readInt();
  43. // 清屏
  44. g.setColor(new Color(red, green, blue));
  45. g.fill3DRect(5, 5, 600, 400, false);
  46. // 利用得到坐标将指定的图形画出来
  47. g.setColor(new Color(green, blue, red));
  48. g.fillOval(x, y, rd, rd);
  49. }
  50. } catch (Exception e) {
  51. e.printStackTrace();
  52. }
  53. }
  54. }
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();
}
}
}

实现的效果也就是小球会在客户端的画布和服务器端的画布上变换着颜色弹动,越弹越大。
效果如下:


 

 
撞了几次墙之后:


 


 
 

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

服务器和客户端的通信绘图相关推荐

  1. Linux socket编程(二) 服务器与客户端的通信

    http://www.cnblogs.com/-Lei/archive/2012/09/04/2670964.html 上一篇写了对套接字操作的封装,这一节使用已封装好的Socket类实现服务器与客户 ...

  2. 基于 HTML5 WebGL 的 3D 服务器与客户端的通信

    这个例子的初衷是模拟服务器与客户端的通信,我把整个需求简化变成了今天的这个例子.3D 机房方面的模拟一般都是需要鹰眼来辅助的,这样找产品以及整个空间的概括会比较明确,在这个例子中我也加了,这篇文章就算 ...

  3. 简单的Java服务器和客户端的通信

    系列文章: ESP8266的AP模式与STA模式简单测试 简单的Java服务器和客户端的通信 STM32 ESP8266和Java服务器透传模式下的双向通信 jsp向servlet传输数据 Servl ...

  4. 基于Python Tkiner、thread与socket实现的简单多人聊天室,在Python中创建TCP服务器与客户端进行通信

    基于Python Tkiner.thread与socket实现的简单多人聊天室,在Python中创建TCP服务器与客户端进行通信 完整代码下载地址:基于Python Tkiner.thread与soc ...

  5. Java实现服务器和客户端简单通信

    Java中网络编程这一块有封装的类库,使用简单,了解原理可以教容易实现服务器和客户端的简单通信. 在编程之前,首先要需要对TCP/IP协议有一定的了解,需要知道Socket套接字的作用以及用法,这个可 ...

  6. 【TCP网络编程】C语言实现TCP服务器和客户端之间的通信(linux)

    功能描述 利用TCP网络通信实现客户端和服务器的通信 服务器代码 server.c #include<stdio.h> #include<sys/socket.h> #incl ...

  7. 【python网络编程】创建TCP/UDP服务器进行客户端/服务器间通信

    客户端/服务器网络编程介绍 套接字:通信端点 实例:客户端发送数据,接收服务器返回的时间戳 用Python 编写FTP 客户端程序 客户端/服务器网络编程介绍 软件服务器也运行在一块硬件之上,但是没有 ...

  8. Android简单实现Socket通信,客户端连接服务器后,服务器向客户端发送文字数据

    案例实现的是简单的Socket通信,当客户端(Android客户端)连接到指定服务器以后,服务器向客户端发送一句话文字信息(你可以拓展其它的了) 先看一下服务端程序的实现吧 Server.java i ...

  9. linux 多线程客户端服务端通信,[转载]多线程实现服务器和客户端、客户端和客户端通信;需要代码,留言...

    一.实验名称 动手打造自己的 IM 二.实验目的 1本次实验旨在锻炼大家的Socket编程能力,以日常生活中广泛使用的IM软件为背景,培养大家对于网络编程的兴趣. 2.通过本次实验,培养linux环境 ...

  10. python安卓开发实例_python服务器与android客户端socket通信实例

    本文实例讲述了python服务器与android客户端socket通信的方法.分享给大家供大家参考.具体实现方法如下: 首先,服务器端使用python完成,下面为python代码: #server.p ...

最新文章

  1. Webpack 4.0 打包 Vue 应用时出现无法使用Vue-loader问题及解决方法
  2. 人人都来写算法 之 快速排序
  3. Java-Java5.0注解解读
  4. 自动化测试基础之Python常见问题
  5. 缓慢的http拒绝服务攻击 tomcat_常见的网络攻击类型
  6. configure 查找依赖库_Rust在编译Android的库时,如何设定依赖的第三方库引用的C/C++的动态库的搜索路径?...
  7. 【贯穿】.NET6结合Docker傻瓜式实现容器编排
  8. IOS 定义手势监听器详解,利用 UIGestureRecognizer 进行捏合、旋转、平移、点击、长按手势事件响应
  9. 二级公共基础知识_计算机二级选择题(公共基础知识)
  10. 互惠互赢,英国将为中国大数据注入新活力
  11. html判断sql没结果,SQL存储过程测试(8)——当待测存储过程没有返回值的时候 如何判断测试结果是否通过...
  12. 区块链应用 | 区块链的火爆会一直持续吗?
  13. 电磁场仿真——绘制电场线和等势线
  14. python办公自动化练习——体温
  15. M1 Mac YYKit 报错
  16. 百度AI之图像识别SDK:车牌识别
  17. 磁珠 符号_史上最全面的磁珠知识大全
  18. 第十九届泳联水中运动世锦赛
  19. jsp网页在线编辑器
  20. mysql数据库网课_中国大学MOOCMysql数据库系统网课答案

热门文章

  1. 调用远程摄像头进行人脸识别_怎样快速搭建人脸识别通道?
  2. 在java中定义一个字符串类型的变量str的语句是:( )._JAVA复习题
  3. 多目标跟踪算法 | FairMOT
  4. 批量创建文件夹并命名的方法
  5. 基于深度区域的金字塔神经网络用于铝合金表面各种缺陷的自动检测和多分类—论文笔记
  6. mvn命令及生命周期
  7. 笔记本电脑CPU选型与插槽型号
  8. 验证性因子分析(一)
  9. 小米路由器显示DNS服务器设置错误,小米路由器dns地址怎么设置
  10. 【运维面试】面试官: 你们公司的上线流程是怎么样的?