初识通信:什么是通信?什么是端口?
首先,我们来看看点对点聊天:
1.我们先创建一个服务器对象,为了能够同时存在多个客户端,我们选择了多线程操作;
public class Jtp { public static void main(String[] args) { Jtp cs = new Jtp() ; cs.setUpServer(9090) ; } public void setUpServer(int port){ try{ //建立绑定在指定端口上的服务器对象 ServerSocket server = new ServerSocket(port) ; System.out.println("服务器创建成功!" + port) ; //让服务区进入等待状态:阻塞状态 while(true){ Socket client = server.accept() ; System.out.println("客户端的Ip地址是"+client.getRemoteSocketAddress()); //调用处理连接对象的方法去处理连接对象 //创建一个线程对象是传入进入的连接 ServerThread st = new ServerThread(client) ; st.start() ;//启动这个线程,去处理连接 System.out.println("已启动了一个线程去处理这个连接对象了") ; } }catch(Exception ef){ ef.printStackTrace(); } } }
2.创建线程类,控制输入输出流
class ServerThread extends Thread{ private Socket client ; //线程对象要处理的连接变量 private OutputStream out ; //输出流对象 /* * 创建这个线程对象时,传入一个它要处理的连接对象 */ public ServerThread(Socket sc){ this.client = sc ; } //将发送消息的代码包装到一个方法中 public void sendMsg2Me(String msg) throws Exception{ byte[] data = msg.getBytes() ; out.write(data);//用输出对象发送 out.flush(); } public void run(){ //在线程run中调用处理连接的方法 try { processChat(this.client) ; } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } //处理方法执行完毕后,线程自己即退出 } //处理客户机进入的连接对象 private void processChat(Socket client) throws Exception{ //从连接对象上的到输入输出流对象 OutputStream out = client.getOutputStream(); InputStream ins = client.getInputStream(); String s = "皇妃是个SB" ; byte[] data = s.getBytes();//取得组成这个字符串的字节 out.write(data) ;//用输出对象发送数据 out.flush();//强制输出 //调用读取字符串的方法,从输入流中读取一个字符串 String inputS = readString(ins) ; while(!inputS.equals("bye")){ System.out.println("客户机说:" + inputS) ; s ="服务器收到:" + inputS +"\r\n" ; data = s.getBytes();//取得组成这个字符串的字节 out.write(data) ;//用输出对象发送! out.flush();//强制输出 inputS = readString(ins) ;//读取客户机的下一次输入 } s = "你好,欢迎再来!\r\n" ; data = s.getBytes(); out.write(data) ; out.flush(); client.close() ;//关闭与客户机的连接 } /* * 从输入流对象中读取字节,拼成一个字符串返加 * 如果读到一个字节值为13,则认为以前的是一个字符串 */ private String readString(InputStream ins) throws Exception{ //创建一个字符串缓冲区 StringBuffer stb = new StringBuffer() ; char c = 0 ; while(c!=13){ //遇到一个换行,就是一句话 int i = ins.read();//读取客户机发来的一个字节; c =(char) i ;//将输入的字节转换为一个char stb.append(c) ; } //将读到的字节组转换为字符串,并调用trim去掉尾部的空格 String inputS = stb.toString().trim(); return inputS ; } }
//以后我们读取的时候可以采用BufferedReader 对InputStream进行封装
例 :
BufferedReader brd = new BufferedReader(new InputStream(ins)) ;
brd.readLine();//读取一行字符串,以换行结束
@ 2.我们现在开始实现多人聊天,并加上界面:
我们首先要创建一个服务端,和一个客户端,然后客户端可以实例化很多的客户,然后通过服务器
来达到群聊的目的。
第一步:我们首先来写一个服务器:
(1)创建一个窗体类,并带有主函数
public class ServerJFrame extends JFrame{ private ChatServer f ; private JTextArea ji ;//显示框 private JTextArea jo ;//输入框 public static void main(String[] args) { new ServerJFrame().socketjf() ; } public void socketjf(){ this.setTitle("服务器"); this.setSize(600,600) ; this.setDefaultCloseOperation(3) ; this.setLocationRelativeTo(null) ; this.setLayout(null) ; JButton jb1 = new JButton("start") ; JButton jb2 = new JButton("send"); final JTextField jf1 = new JTextField(5) ; ji = new JTextArea(5,20) ; JLabel la =new JLabel("要发送的消息"); jo = new JTextArea(5,20); ji.setEditable(false) ; this.add(ji) ; this.add(la) ; this.add(jo); this.add(jb1); this.add(jf1) ; this.add(jb2); ji.setBounds(10, 20, 550, 200) ; la.setBounds(50, 230, 550, 20) ; jo.setBounds(10,250,550,100) ; jb2.setBounds(180,370,200,50) ; jb1.setBounds(50,450,200,50) ; jf1.setBounds(300,450,200,50) ; this.setVisible(true) ; ActionListener t = (new ActionListener(){//内部类实现 int t ; public void actionPerformed(ActionEvent e) { if(e.getActionCommand().equals("start")){ // System.out.println("dainifei") ; t = Integer.parseInt(jf1.getText()) ; ChatServer f = new ChatServer(t ,ji);//创建ChatServer类 f.start();//开始线程启动服务器 接收多个客户端 } if(e.getActionCommand().equals("send")){ String sd = jo.getText(); ji.append("客户端说: " +sd+"\t\n"); jo.setText(null) ; for(int i=0;i<SocketList.lt.size();i++){ ServerThread t = SocketList.lt.get(i); t.sendMessage("客户端说: " +sd) ; // t.StringRead(ins); } } } }); jb1.addActionListener(t); jb2.addActionListener(t); } }
(2)创建一个SocketList类来创建一个队列,储存客户的信息;我们可以采取静态方法,这样就会变得方便些;
/* * 静态队列,用于存储ServerThread对象 */ public class SocketList { public static ArrayList<ServerThread> lt= new ArrayList<ServerThread>(); public static void add(ServerThread s){ lt.add(s) ; } }
(3)创建服务器类:
public class ChatServer extends Thread{ private int port ; Socket socket ; ServerThread f ; private JTextArea ji ; int i=1 ; public ChatServer(int port,JTextArea ji ){ this.port = port ; this.ji= ji; } public void server(int port){ try { ServerSocket server = new ServerSocket(port); System.out.println("创建服务器"+port); while(true){ socket = server.accept(); System.out.println("客户的地址是"+socket.getRemoteSocketAddress()); ServerThread f = new ServerThread(socket,ji); f.start(); f.setUser("用户"+ i ); SocketList.add(f) ; i =i +1 ; } } catch (Exception e) { e.printStackTrace(); } } public void run(){ server(port) ; } }
在这里,每创建一个客户对象,我们就把它加到队列中去,并为其注上名字标识
ServerThread:
控制 多个客户的接收,输出消息;
/* * 这个线程主要用于接收多个客户端 */ class ServerThread extends Thread{ private OutputStream out ; private Socket socket ; private JTextArea ji ; private BufferedReader brd ; private InputStream ins ; private String user ; //接收从ServerJFrame中传来的 JTextArea对象,和从ChatServer传来的Socket对象 public ServerThread(Socket socket,JTextArea ji){ this.socket = socket ; this.ji = ji ; } public String getUser(){//我将用户名进行了封装,写了它的getter和setter方法 return this.user ; } public void setUser(String s){ this.user =s ; } //实现发送信息给用户,这个方法可以不用加入线程 public void sendMessage(String msg) { try { msg +="\r\n" ; this.out.write(msg.getBytes()) ; this.out.flush(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void run(){ processChat(socket) ; } //该方法实现从客户端接收信息然后对信息进行处理的操作 public void processChat(Socket socket){ try { //获得Socket的输入输出流对象 out = socket.getOutputStream(); ins = socket.getInputStream() ; brd = new BufferedReader(new InputStreamReader(ins));//对InputStream进行封装 String s = "欢迎你来"; sendMessage(s) ; out.flush(); StringRead(this.ins) ; while(!s.equals("bye")){ out.flush(); StringRead(ins) ; } s="再见,欢迎再来" ; sendMessage(s); out.flush(); socket.close(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } //从客户端接收信息的方法 public void StringRead(InputStream ins) throws Exception{ // StringBuffer sb = new StringBuffer(); // char c= 0 ; // while(c!=13){ // int t = ins.read(); // c =(char)t ; // sb.append(c) ; // } // String inputs = sb.toString().trim(); // return inputs ; String input = brd.readLine();//读出一行字符 System.out.println("kehuduan"+input); ji.append(user +"说 "+input+"\r\n");//将读到的信息传递到显示框 for(int i=0;i<SocketList.lt.size();i++){ ServerThread t = SocketList.lt.get(i);//运用队列将得到的信息发给所有客户端 t.sendMessage(user+"说 "+input) ; // t.StringRead(ins); } } }
这样我们已经基本完成了服务端,我们来测试一下:
这样,服务端就完成了
下面我们来实现客户端:
首先,同样的,我们写一个界面,主函数类:
public class RocketJframe extends JFrame{ private JTextArea ji ; private RocketServer fd ; private JTextArea jo ; public static void main(String[] args) { new RocketJframe().socketjf() ; } public void socketjf(){ this.setTitle("客户端"); this.setSize(600,600) ; this.setDefaultCloseOperation(3) ; this.setLocationRelativeTo(null) ; JButton jb1 = new JButton("start") ; JButton jb2 = new JButton("send"); final JTextField jt1 = new JTextField(10); final JTextField jt2 = new JTextField(10); this.setLayout(null) ; ji = new JTextArea(5,20) ; JLabel lb = new JLabel("输入IP地址") ; JLabel la =new JLabel("要发送的消息"); JLabel lc = new JLabel("输入端口号"); jo = new JTextArea(5,20); ji.setEditable(false) ; this.add(ji) ;//显示框 this.add(la) ;//发送消息的标签 this.add(jo);//输入框 this.add(jb1);//start按钮 this.add(jt1);//ip地址文本框 this.add(jt2) ;//端口号 this.add(jb2); //send按钮 this.add(lb) ;//"输入IP地址" this.add(lc) ;//"输入端口号" ji.setBounds(10, 20, 550, 200) ; la.setBounds(50, 230, 550, 20) ; jo.setBounds(10,250,550,100) ; jb2.setBounds(180,370,200,50) ; jb1.setBounds(180,420,200,50) ; lb.setBounds(10,420,100,50) ; lc.setBounds(460,420,100,50) ; jt1.setBounds(10, 500, 100, 50) ; jt2.setBounds(480, 500, 100, 50) ; this.setVisible(true) ; ActionListener t = (new ActionListener(){ public void actionPerformed(ActionEvent e) { f(e.getActionCommand().equals("start")){ String gh = jt1.getText(); int th = Integer.parseInt(jt2.getText()) ; fd = new RocketServer(gh,th,ji);//实例化RocketServer类 if(fd.server()){ fd.start(); //启动线程,接收服务器发来的信息 } } if(e.getActionCommand().equals("send")){ String msg = jo.getText() ;//取得输入框写入的信息 jo.setText(null) ;//设置写完后清空输入框 fd.sendMessage(msg);//将输入框的信息发送给服务器 } }}); jb1.addActionListener(t); jb2.addActionListener(t); } }
然后写一个输入输出流的线程类:
public class RocketServer extends Thread{ private int port ; private OutputStream out ; private Socket socket ; private BufferedReader brd; private JTextArea jt ; String ip ; String inputs ; //需要把ip地址,端口号,和文本框对象传过来 public RocketServer(String ip,int port,JTextArea jt){ this.ip = ip ; this.port = port ; this.jt =jt ; } public boolean server(){//判断是否能够连接上服务端 try { //连上了就创造Socket对象 socket = new Socket(this.ip,this.port) ; out = socket.getOutputStream() ; InputStream ins = socket.getInputStream() ; brd = new BufferedReader(new InputStreamReader(ins)); return true ; } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return false ; } public void run(){ while(true){ readFromServer(); } } public void readFromServer(){//读取服务端的信息的方法 try { String input = brd.readLine(); System.out.println("服务器"+input); jt.append(input + "\r\n") ; //将收到的信息传到显示框 } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void sendMessage(String msg) { //将信息发送给服务端的方法 try { msg += "\r\n"; out.write(msg.getBytes()) ; out.flush() ; } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
下面我们的客户端就做好了,可以看看效果:
其中,让我有点不解的就是接受数据问题,后来吧接受反倒线程中就成功的解决了。恩,我要讲的就这些了。下次继续图片的传输
相关推荐
Spring Boot整合websocket实现群聊,音频发送,点对点聊天,图片发送。 Spring Boot整合websocket实现群聊,点对点聊天,图片发送,音频发送。 Spring Boot整合websocket实现群聊,点对点聊天,图片发送,音频发送 ...
# 功能点描述 * 访问页面时,ajax请求返回在线用户。(非实时) * 用户名ajax校验是否重名。 * 建立连接后,订阅user、lobby、private通道。(实时接收消息) * 消息角标提醒。 * 与不同用户的聊天界面切换。 ## ...
mqtt-socketIo-php用 nodejs ,php ,mqtt 实现的IM聊天系统,实现了 1: 点对点聊天和群聊 。2:实现了PC和移动设备的通信。(android的代码暂未提供)。
基于python的聊天室程序,有完整源代码!! 已完全中文化,同时附有课程设计作业报告!!! 功能简介: ... 私聊点对点视频、音频聊天 支持分辨率调节 支持IPv4、IPv6 可以选择是否在桌面上显示自己
用Java做的针对点对点通信(ServerSocket Socket)的小程序,包括收发信息,用swing开发界面,使用beautyeye美化的界面(高手写的,网上有) 使用说明: 1、将项目在导入eclipse中, 2、先运行...
(1)网上聊天使人们之间的通信变得越来越方便,快捷,准确,及时。 (2)还可以在网上认识新的朋友,交流自己的一些想法。 三 系统的总体分析与设计 分析该聊天室系统,制订整个系统框架,主要要求及特点如下: 1....
基于网络聊天应用的普及,以VC++6.0为平台,采用MFC控件设计聊天程序的对话框实现基于TCP/IP协议的点对点聊天工具。本聊天工具通过输入服务器端的IP地址将客户端和服务器端连在一起,实现两者间的实时通信,并提供...
ubuntu下QT开发的聊天工具,实现单聊群聊,离散消息,聊天采用点对点的udp方式,客户端与服务器的通信采用tcp连接。基本上没有注释,呵呵,看起来应该很费心,文件包含整个开发过程的代码,存了很多副本,基本上实现...
点对点的文本通信 点对点的图片传输 点对点的文件传输 群聊与私聊功能的实现 在线好友的查询 有好的人机交互界面 聊天记录查询 分时贵了点 可是是好东西 物有所值 内带实验报告 和 课题实践报告
通信规范的制定主要跟老师给出的差不多,并做了一小点增加: (增加验证用户名是否与聊天室已有用户重复,在服务器给客户端的消息中,增加标志0) ① TCP/IP数据通信 --- “聊天”消息传输格式 客户机 - 服务器...
局域网聊天工具,可实现好友上线时自动更新列表,私聊,邀请群聊,点对点文件发送,还存在一些bug未解决:不能发送文件夹,且为单线程,即不能同时给两个好友发送文件,也不能同时接收两个好友发送的文件,会串。...
方便:支持文本、音频、视频通话安全:点对点端对端加密,没有中心服务器简单:qTox使用简单,不需要任何专业知识,你只要专注于聊天自由:qTox是完全免费的。除了免费使用,还能自由修改它qTox使用首先qTox是点对点...
用 nodejs ,php ,mqtt 实现的IM聊天系统,实现了 1: 点对点聊天和群聊 。2:实现了PC和移动设备的通信。(android的代码暂未提供)。 软件开发设计:PHP、QT、应用软件开发、系统软件开发、移动应用开发、网站开发...
系统要求实现局域网内部的自由交流,包括点对点以及群聊、文件的传输,方便局域网内部人员的交流。 简要来说,我们提供了用户的注册登录、文件的收发、好友之间对话、好友间的增删查改、好友列表、主界面的布局等...
IM(Instant Message)功能:用户登录后能进行实时多方点到点短消息通信,如聊天。 消息记录:能保存聊天记录到本地。 文件传输:能进行双方文件传输,能显示文件传输进度。 断点重传:支持断点重传,若传输文件过程中...
所用技术:java,oracle 开发工具:eclipse,oracle10g 项目描述:及时网络通信系统主要是针对一个...主要功能:用户登录,用户的注册,点对点聊天,群聊,文件的上传下载,用户签到签退,聊天信息记录,用户的增删改查
支持群聊与点对点聊天。当前包括 Android客户端、iOS客户端与 Java服务器端。3分钟就可以整套系统跑起 软件开发设计:PHP、QT、应用软件开发、系统软件开发、移动应用开发、网站开发C++、Java、python、web、C#等...
基于点对点的聊天,持续的群聊,音频,视频会议和实时流媒体,电话会议它包括第三方产品,特别是: 项目; 项目; Web客户端。 项目。基于项目的桌面客户端。 实时流式传输到rtmp服务器(如you-tube)。 Pade可与...