进入了通信阶段,感觉和之前学的内容差异很大,对这方面也没有之前那么感兴趣……有点缺乏热情进

度上不来……同时还在改进之前的线程游戏,很久没更新了。做了可以连接多个客户端,群发消息的服务

器,和可以同步画图的画板,一起总结一下。

1.思路:
需要实现的功能:
服务器:
1.创建一个连接
2.被客户端连接,将线程加入一个队列中。
3.打开客户端的输入输出流
4.将消息写入客户端的输出流
5.群发,遍历整个队列,将数据写入每个客户端的输出流。
6.读入客户端写入自身输出流的内容,再按照协议表达。

客户端:
1.连接服务器
2.打开服务器的输入输出流
3.读取服务器写入自身输入流的数据,按照协议表达。
4.把需要传递的内容写入服务器的输入流中,再由服务器调用群发方法,实现客户端与客户端之间的交流

感觉通信和之前学习的内容有个很大的区别,就是程序的每个部分都是紧密关联的,环环相扣,哪一个部

分出了问题都出不了效果。需要在思绪清晰的时候写。之前几天原理不太明确走了很多弯路。

服务器和客户端的写法都可以简化为几步:

服务器:
1.创建服务器
2.进入等待状态 accept
3.获取输入输出流

客户端:
1.new socket
2.获取输入输出流

其他功能的实现,只需定义不同的协议,就能实现。

2.服务器和客户端一起所需要的类比较多,一开始写因为类名规定不合理给自己添加了许多麻烦。这里稍

微提一下:
服务器:
服务器界面类:ServerUI;
服务器创建线程:CreatServer
服务器读写线程:ServerThread
服务器群发类:ChatConnect

客户端:
客户端界面:ClientUI
客户端读写线程:ClientThread

还有各种监听器,和辅助类,那就根据需求来。
姑且服务器相关的都以Server打头,客户端的都以Client打头好了。

服务器界面1:

客户端界面1:

3.新涉及的类
1.类 Socket

public class Socketextends Object此类实现客户端套接字(也可以就叫“套接字”)。套接字是两

台机器间通信的端点。

套接字的实际工作由 SocketImpl 类的实例执行。应用程序通过更改创建套接字实现的套接字工厂可以

配置它自身,以创建适合本地防火墙的套接字。

涉及的用法:
while(true){
//阻塞
Socket client=s.accept();
System.out.println("进入连接:"+client.getRemoteSocketAddress());
方法:
getRemoteSocketAddress()
返回此套接字连接的端点的地址,如果未连接则返回 null。

2.类 ServerSocket
此类实现服务器套接字。服务器套接字等待请求通过网络传入。它基于该请求执行某些操作,然后可能向

请求者返回结果。

服务器套接字的实际工作由 SocketImpl 类的实例执行。应用程序可以更改创建套接字实现的套接字工

厂来配置它自身,从而创建适合本地防火墙的套接字。

涉及的用法:
java.net.ServerSocket s=new java.net.ServerSocket(this.port);
System.out.println("服务器创建成功!"+port);

方法:
accept()
侦听并接受到此套接字的连接。

3.telnet
在最开始调试服务器时,使用了一个WINDOWS自带的简易客户端,telnet。
连接服务器的格式:
telnet IP 端口号。
另外在CMD中使用指令:ipconfig 可以获取主机的IP地址

3.在网络画板部分实现的功能:
1.切换画笔类型(划线画圆画方框)
2.多客户端连接服务器
3.群画群聊

服务器界面2:

客户端界面2:

源代码:

创建线程:

import java.awt.Graphics;
import java.net.Socket;import javax.swing.JTextArea;public class creatThread extends Thread{private int port;private int count;private Graphics g;private JTextArea JA;public chatThread ct;public creatThread(int port,JTextArea JA,int count,Graphics g){this.port=port;this.JA=JA;this.count=count;this.count++;this.g=g;}  public void run(){creatchat();}private void creatchat() {try{java.net.ServerSocket s=new java.net.ServerSocket(this.port);System.out.println("服务器创建成功!"+port);//让服务器进入循环等待状态while(true){//阻塞Socket client=s.accept();System.out.println("进入连接:"+client.getRemoteSocketAddress());//创建线程ct=new chatThread(client,JA,g);this.setchatThread(ct); //保存至队列Chatconnect.add(ct);ct.start();
//    }}catch(Exception ef){ef.printStackTrace();}}public void  setchatThread(chatThread ct){this.ct = ct;}public chatThread getchatThread(){return this.ct;}
}

服务器线程:

public class chatThread extends Thread{private Socket client;private  OutputStream ous;private  InputStream ins;private JTextArea JA;int count;static Graphics g;DataInputStream dins;DataOutputStream dous;ServerMouse sm;public chatThread(Socket client,JTextArea JA,Graphics g){this.client=client;this.JA=JA;this.g=g;}public void run(){processChat();}public  void processChat() {try{  //从通话对象上获取输入输出流ins=this.client.getInputStream();ous=this.client.getOutputStream();dins=new DataInputStream(ins);dous=new DataOutputStream(ous);} catch(Exception ef){ef.printStackTrace();}//服务器读入客户端发来的数据while(true){try {
//                String msg=("welcom!\r\n");
//                 byte[] bb=msg.getBytes();
//                 ous.write(bb);byte b = dins.readByte();System.out.println("服务器读入,type="+b);if(b==1){int x1 = dins.readInt();int y1 = dins.readInt();int x2 = dins.readInt();int y2 = dins.readInt();System.out.println("画线  "+"x1="+x1+",y1="+y1+",x2="+x2+",y2="+y2);g.drawLine(x1, y1, x2, y2);Chatconnect.sendmsg(1,x1,y1,x2,y2);}if(b==2){int x1 = dins.readInt();int y1 = dins.readInt();int x2 = dins.readInt();int y2 = dins.readInt();System.out.println("画圆  "+"x1="+x1+",y1="+y1+",x2="+x2+",y2="+y2);g.drawOval(x1, y1,Math.abs(x1-x2), Math.abs(y1-y2));Chatconnect.sendmsg(2,x1,y1,x2,y2);}if(b==3){int x1 = dins.readInt();int y1 = dins.readInt();int x2 = dins.readInt();int y2 = dins.readInt();System.out.println("画方框  "+"x1="+x1+",y1="+y1+",x2="+x2+",y2="+y2);g.drawRect(x1, y1,Math.abs(x1-x2), Math.abs(y1-y2));Chatconnect.sendmsg(3,x1,y1,x2,y2);}
//                      //发送消息
//                      if(b==4){
//                          System.out.println("服务器发送消息");
//                           String s=readString(ins);
//                           this.JA.append("客户端"+count+":"+s+"\r\n");
//                             System.out.println("服务器写入运行!");
//                             System.out.println("user: "+s);
//                             Chatconnect.sendmsg(s);
//                             msg="host:"+s+"\r\n";
//                             bb=msg.getBytes();ous.write(b);
//                             s=readString(ins);
//                      }} catch (Exception e) {e.printStackTrace();}}}//   public static void writeLine(int x1,int y1,int x2,int y2){
//      try{
//       dous.writeInt(1);
//       dous.writeInt(x1);
//       dous.writeInt(y1);
//       dous.writeInt(x2);
//       dous.writeInt(y2);
//       }catch(Exception ef){
//              ef.printStackTrace();
//          }
//  }
//
//  //字符读入
//  private String readString(InputStream ins) {
//      try{
//             StringBuffer sb=new StringBuffer();
//             int t=ins.read();
//             while(t!='#'){
//                 sb.append((char)t);
//                 t=ins.read();
//             }
//             String s=sb.toString();
//             return s;
//            }catch(Exception ef){
//                ef.printStackTrace();
//            }
//            return "error";
//         }
//
//  public void sendmsg(String msg) {
//      try{
//          ous.write(4);
//          msg+="#";
//          ous.write(msg.getBytes());
//          }catch(Exception ef){
//              ef.printStackTrace();
//          }
//
//  }public void sendmsg(int type,int x1,int y1,int x2,int y2) {try {System.out.println("服务器输出,TYPE="+type);if(type==1){//画线dous.writeByte(1);dous.writeInt(x1);dous.writeInt(y1);dous.writeInt(x2);dous.writeInt(y2);}if(type==2){//画圆dous.writeByte(2);dous.writeInt(x1);dous.writeInt(y1);dous.writeInt(x2);dous.writeInt(y2);}if(type==3){//画方框dous.writeByte(3);dous.writeInt(x1);dous.writeInt(y1);dous.writeInt(x2);dous.writeInt(y2);}} catch (IOException e) {e.printStackTrace();}}}

4.调试心得

关于参数的传输:这里加入了鼠标监听器,当初在传送数据的时候纠结了一下。最后使用的方法是在监听

器里画好图后,然
后再调用线程中的方法,传入线程中,写入输出流中。

关于群发的实现思路:在实现客户端之间的交流时,思路上也走了弯路。虽然想法比较奇特,但是应该也

能实现,不知道为什么出了错误。最后换成了更加正常的思路:在监听器里画完图后,调用线程中的方法

写入服务器的输出流中。服务器的输入流获取信息之后,立即调用群发方法。

关于不同类型数据的传输:这里就关于协议了。一般的方式是定一个方式,先输出一个类型码,代表数据

类型,读取时再通过数据类型辨别,分别处理。

通信(服务器客户端的群聊与网络画板)相关推荐

  1. java群聊_Java Socket通信实现私聊、群聊

    前言 闲言少叙,上代码! 代码编写 server服务端 /*** 服务端*/ public classServer {private static ServerSocket server = null ...

  2. soul群聊显示服务器异常,soul群聊状态是什么

    soul是一个非常好用的灵魂社交软件,很多用户都会注册这个平台的账号,然后使用手机进行使用,软件的社交方式非常的特别,主要是使用语音进行社交,保证是真人社交,但是不会有其他的信息出现,所以都是进行思想 ...

  3. soul群聊派对显示服务器异常,Soul群聊派对玩法攻略

    Soul是一个线上语音社交软件,这里有很多丰富的社交资源可以使用,这款软件追求的是一种灵魂社交的一种自然社交方式,用户可以通过这个社交方法,找到合适自己的灵魂伴侣,超多社交服务都可以轻松体验,用户可以 ...

  4. 【LINUX/UNIX网络编程】之使用消息队列,信号量和命名管道实现的多进程服务器(多人群聊系统)...

    RT,使用消息队列,信号量和命名管道实现的多人群聊系统. 本学期Linux.unix网络编程的第三个作业. 先上实验要求: 实验三  多进程服务器 [实验目的] 1.熟练掌握进程的创建与终止方法: 2 ...

  5. Netty中实现多客户端连接与通信-以实现聊天室群聊功能为例(附代码下载)

    场景 Netty的Socket编程详解-搭建服务端与客户端并进行数据传输: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/1086 ...

  6. 《OnlineChat996》基于微信群聊的在线实时通信工具

    项目源码:你和我的畅聊时光 一.主要功能 注册,成为我们的注册会员用户,你将拥有全网唯一的ID. 登录,进入拥有千万好友的畅聊空间. 私聊,你可以选择和任意在线用户进行一次亲密对话. 群聊,只要你想, ...

  7. python开发微信群_Python编程:微信群聊程序的开发与进/线程知识汇总(附代码)

    本文承接上篇文章的客户端-服务器聊天对话程序,进一步设计开发了微信群聊的python模拟程序,涉及的python知识点为:Python实战:聊天软件开发与TCP/Socket编程知识汇总(附代码)和 ...

  8. ASP.NET SignalR 与LayIM配合,轻松实现网站客服聊天室(四) 添加表情、群聊功能...

    休息了两天,还是决定把这个尾巴给收了.本篇是最后一篇,也算是草草收尾吧.今天要加上表情功能和群聊.基本上就差不多了,其他功能,读者可以自行扩展或者优化.至于我写的代码方面,自己也没去重构.好的,我们开 ...

  9. Java如何实现不同局域网TCP通信+群聊(云服务器实现)

    最近在CSDN上学习了Socket通信群聊的方法,就觉得这样就可以实现QQ的样子了.然后让女朋友用电脑试了一下,运行用户端代码,发现连连接到服务器都做不到.后来经过自己的研究,实现了QQ群聊的功能,后 ...

最新文章

  1. SpringBoot (五) :SpringBoot整合mybatis
  2. 02_c3p0之c3p0-config.xml配置案例,操作c3p0的jdbcUtil工具类的编写
  3. SAP UI5 应用开发教程之二十九 - SAP UI5 的路由和导航功能介绍试读版
  4. 《Android应用开发攻略》——2.14 备份Android应用程序数据
  5. Java ObjectOutputStream reset()方法与示例
  6. python入门心得_一天入门 Python 的一些心得
  7. idea复制maven项目,source root为原项目的解决方法
  8. java-Comparable和Comparator的用法
  9. 如何用计算机管理员权限,计算机管理员权限在哪里设置_电脑系统如何设置管理员权限-win7之家...
  10. Linux 命令(78)—— rmdir 命令
  11. Android移动端性能测试工具mobileperf
  12. Android Notification中PendingIntent.Flag的应用
  13. RNN分类IMDB电影评分
  14. mysql migration toolkit下载_MySQL Migration Toolkit
  15. 温度转换(摄氏温度转化氏温度)
  16. 扑克牌游戏“快算24”算法
  17. sqlite数据库的版本更替
  18. IDEA输入字母间距变大报红
  19. 吃透 Vue 项目开发实践|16个方面深入前端工程化开发技巧【上】
  20. 初中教师资格证计算机试题,2017上半年初中语文教师资格证面试试题(精选)第二批...

热门文章

  1. 宏碁传奇Go评测 怎么样
  2. FPGA入门学习记录(1)----自动售货机(VM_FSM)
  3. iView级联选择器Cascader回显慢的问题
  4. 微软官方原版WindowsXP Pro With Sp2简体中文VOL版
  5. 解决idea代码无故爆红问题
  6. 关于心理咨询师与咨询者的讨论
  7. 【深度学习基础1】深度学习发展历史
  8. NumPy基础之大作业(Iris数据分析)
  9. 36艺教育完成3000万元Pre-A轮融资,星火资本投资 1
  10. Sourcetree git status失败 错误代码128:error :bad signature 0x0000000