`
师大黄飞
  • 浏览: 43970 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

Java基础之聊天器

阅读更多

这是刚开始学习java网络编程的时候做的一个东东,,局域网聊天器,可以在局域网内,和小伙伴聊天,共同画图(游戏原型)。先上图吧



 

一,首先讲解下基本知识,建立网络连接,你首先得有服务器和客户端,

1,服务器:ServerSocket s=new ServerSocket(n);这样就建立好一个端口号n的服务器,如果把你的电脑比作公寓,端口号类似于你的房间号。服务器创建好后,你得等待客户端连接,Socket so=s.accept();这样就能获取到连接进来的客户端(如果当前么有人连进来,他就会阻塞在当前,不会执行下面的代码),然后你就得获取他的输入输出流,用来传送和接收数据,InputStream is=so.GetinpputStream();Outputstream ou=so.getOutPutstream();

2,客户端:Socket s=new Socket("ip",端口号);ip就是你连接的那台服务器的电脑的ip地址,端口号就是你创建服务器的那个端口号,也就是说你得先找到公寓地址,然后再去找房间,这样就连接好了,同样的获取输入输出流,用来传送接收数据。

二,以上就是基本知识点,现在开始实例代码

首先看界面代码

 

public  class fu extends JFrame{
	public Test t=new Test();
	private static JTextArea jt3;
	public JTextField jt2;
	static Graphics gr;
public void UI(){
	this.setTitle("服务器");
	this.setSize(400,400);
	this.setLocation(400,200);
	this.setLayout(new FlowLayout(FlowLayout.LEFT));
	this.setDefaultCloseOperation(3);
	JButton jb1=new JButton("start");//启动服务器按钮
	this.add(jb1);
	JTextField jt1=new JTextField();//输入消息框
	jt1.setPreferredSize(new Dimension(40,30));
	this.add(jt1);
	JButton jb2=new JButton("send");//发送按钮
	this.add(jb2);
	 jt2=new JTextField();
	jt2.setPreferredSize(new Dimension(180,30));
	this.add(jt2);
	 jt3=new JTextArea();
	jt3.setPreferredSize(new Dimension(400,150));
	this.add(jt3);
	JPanel jp=new JPanel();
	jp.setPreferredSize(new Dimension(400,150));
	this.add(jp);
	this.setVisible(true);
	gr= jp.getGraphics();
	Test t=new Test();
	fhj fh=new fhj(this,t);
	jp.addMouseListener(fh);
	fujian f=new fujian(jt1,jt2,t);
	jb1.addActionListener(f);
	jb2.addActionListener(f);
}
public static void setjt3(String s){
	jt3.setText(s);
}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
       fu f=new fu();
       f.UI();
	}

}

 按下start触发事件fujian中的“start”

package First;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JTextField;

public class fujian  implements ActionListener {
	public JTextField jt1,jt2;
	public Test tt; 
	public fujian( JTextField jt1,JTextField jt2,Test tt ){
		this.jt1=jt1;
		this.jt2=jt2;
		this.tt=tt;
	}
	int co=0;
	@Override
	public void actionPerformed(ActionEvent e) {
	
		// TODO Auto-generated method stub
		if(e.getActionCommand().equals("start")){
			
			if(co==0){
			fuxian u=new fuxian(jt1,tt);
			u.start();
			co=1;
			}else{
				System.out.println("端口已经成功创建无需再创建");
			}
		}
		if(e.getActionCommand().equals("send")){
			for(int i=0;i<tt.l.size();i++){
				try {
					tt.l.get(i).qunfa(jt2.getText());
				} catch (Exception e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}
		}
	}

}

 启动一个线程fuxian u=new fuxian(jt1,tt); u.start();来启动服务器

package First;

import javax.swing.JTextField;

public class fuxian extends Thread{
	public JTextField jt;
	public Test tt; 
public fuxian(JTextField jt,Test tt){
	this.jt=jt;
	this.tt=tt;
}
public void run(){
	int x=Integer.parseInt(jt.getText());
	tt.set(x);
}
}

 

启动服务器的具体方法是Test类中的set()方法

package First;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;

import org.omg.CORBA_2_3.portable.OutputStream;

public class  Test {
public  ArrayList<Tx> l=new ArrayList<Tx>();
public void  set(int x) {
	//建立绑定在指定端口傻瓜的服务器
	ServerSocket se;
	try {
		se = new ServerSocket(x);
		System.out.println("服务器创建成功"+x);
		Socket c;
		//让服务器进入等待状态:
		while(true){
		c=se.accept();
		Tx t=new Tx(c,this);
		l.add(t);
		System.out.println("目前队列的长度是"+l.size());
		t.start();
	}
	}catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}

	}
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		
	}

}

 其中public  ArrayList<Tx> l=new ArrayList<Tx>();是一个Tx类型的队列,用来存储Tx对象

c=se.accept();
Tx t=new Tx(c,this);
l.add(t);
一旦有客户连接就启动Tx线程,并且将Tx对象存储,现在来看下Tx的具体类容

package First;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Socket;
import java.util.ArrayList;

public class Tx extends Thread {
	public DataInputStream Di;
	public DataOutputStream Do;
	public BufferedReader bf;
	public int j=0;
	public Socket c;
	public String name="",r;
    public java.io.OutputStream out;
	public Test t1;
    public InputStream in;
	public Tx(Socket c,Test t1) throws Exception {
		this.c=c;
		this.t1=t1;
		 in=c.getInputStream();
		 Di=new DataInputStream(in);
		out=c.getOutputStream();
		Do=new DataOutputStream(out);
	}
	public void qunfa(String s) throws Exception{	
      s +="\r\n";
	byte[] data=s.getBytes();
	String t=new String(data);
    System.out.println(t);
    Do.writeByte(1);
	Do.write(data);
	}
public  void jieshou() throws Exception{
	   //out=c.getOutputStream();
	   int k=Di.readByte();
  if(k==0){
		   int x1=Di.readInt();
		   int y1=Di.readInt();
		   int x2=Di.readInt();
		   int y2=Di.readInt();
		   System.out.println("接受成功");
		   fu.gr.drawLine(x1, y1, x2, y2);
		   for(int i=0;i<t1.l.size();i++){
			t1.l.get(i).Do.writeByte(0);
			t1.l.get(i).Do.writeInt(x1);
			t1.l.get(i).Do.writeInt(y1);
			t1.l.get(i).Do.writeInt(x2);
			t1.l.get(i).Do.writeInt(y2);
			//t1.l.get(i).Do.flush();
			System.out.println("传送成功");
			}
  }else if(k==1){
	   System.out.println("正在接受文字");
	   bf=new BufferedReader(new InputStreamReader(in));
	   r=bf.readLine();
		System.out.println(r);
		System.out.println("阅读完毕");
		fu.setjt3(r);
		String g="user"+r;
		g+="\r\n";
		byte[] e=g.getBytes();
		for(int i=0;i<t1.l.size();i++){
			t1.l.get(i).Do.writeByte(1);
			t1.l.get(i).Do.write(e);
			//t1.l.get(i).out.flush();
			System.out.println("执行了-----------"+i);
		System.out.println(r+"文字接受成功");
	}
		}else{
			System.out.println("eeeeeeeeeeeeeeeeeeeee"+k);
		}
	   }
public void X() throws Exception{
	while(true){
		System.out.println("主机接收");
		jieshou();
		}
}
public void run(){
	try {
		X();
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}
}

 由

public void run(){
try {
X();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
看出是线程开启 X();x()里面是个死循环 一直执行jieshou()方法

接收分为两种一种是接收图象,一种接收文字(自己定义的协议)

客户端连接之后开启线程接收,为什么要存储起来呢

这样就能对每一个客户端进行管理了,你可以向某一个客户端发送,或者全部发送(里面的qunfa方法)

上面是服务器接收,现在看服务器发送,这是fujian里面的方法,按下send之后,获取输入框上的东东,调用qunfa发送,其中有一个循环,就是把所有连接进来的客户端Tx对像取出来调用发送方法qunffa()

	if(e.getActionCommand().equals("send")){
			for(int i=0;i<tt.l.size();i++){
				try {
					tt.l.get(i).qunfa(jt2.getText());
				} catch (Exception e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}

 然后就是可以看下如何传送图像

package First;

import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;

public class fhj extends MouseAdapter{
	public Test tt;
	public fu f;
	public int  x1,x2,y1,y2;
	public fhj(fu f,Test tt){
		this.f=f;
		this.tt=tt;
	}
	public void mousePressed(MouseEvent e){
		x1=e.getX();
		y1=e.getY();
		
	}
	public void  mouseReleased(MouseEvent e){
		x2=e.getX();
		y2=e.getY();
		f.gr.drawLine(x1,y1,x2,y2);
		for(int i=0;i<tt.l.size();i++){
		try {
//			tt.l.get(i).Do.writeByte(1);
//			String s="画线成功";
//			s=s+"\r\n";
//			byte[] b=s.getBytes();
			//tt.l.get(i).Do.write(b);
			tt.l.get(i).Do.writeByte(0);
			tt.l.get(i).Do.writeInt(x1);
			tt.l.get(i).Do.writeInt(y1);
			tt.l.get(i).Do.writeInt(x2);
			tt.l.get(i).Do.writeInt(y2);
			System.out.println("发送成功-------------"+tt.l.size());
		
		} catch (Exception e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}}
		
}
	}

 

上面是对画板的监听,首先传入tt.l.get(i).Do.writeByte(0);0,(自己定义的格式,接收方如果首先接收到0,就执行接收图片的方法),然后就是传入线条的四个坐标,(关于鼠标监听,前面的博客java基础画图板有说过),这样服务器这边就写完了

/******************************************下面开始客户端的接收与发送*********************************/

客户端和服务器的接收和发送差不多,所以不再啰嗦

界面

package First;

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
public class ku extends JFrame{
	static String s;
	static Graphics g;
	static JTextArea jt1;
	static JTextArea jt2;
	public void UI(){
		this.setTitle("客户端");
		this.setSize(400,400);
		this.setLocation(400,200);
		this.setLayout(new FlowLayout(FlowLayout.CENTER));
		this.setDefaultCloseOperation(3);
		JButton jb1=new JButton("登录");
		JButton jb2=new JButton("发送");
		 jt1=new JTextArea();
		jt1.setPreferredSize(new Dimension(380,100));
		jt2=new JTextArea();
		jt2.setPreferredSize(new Dimension(380,100));
		JPanel jp=new JPanel();
		this.add(jp);
		jp.setPreferredSize(new Dimension(380,100));
		this.add(jt1);
		this.add(jt2);
		this.add(jb1);
		this.add(jb2);
		this.setVisible(true);
		g=jp.getGraphics();
		kejian ke=new kejian();
		kbj kb=new kbj(this,ke);
		jp.addMouseListener(kb);
		jb1.addActionListener(ke);
		jb2.addActionListener(ke);
	}
	public  static void getjt2(){
		 s=jt2.getText();
	}
	public static void setjt2(){
		jt2.setText("");
	} 
public static void setjt1(){
	jt1.setText(s);
}
public static void setjt1(String st){
	jt1.setText(st);
}
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
ku t=new ku();
t.UI();
	}
}

 

然后是连接和接收的方法,

package First;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

public class kehu extends Thread{
	public int j=2;
public int i=0;
public BufferedReader bu;
public String ip;
public int pot;
public StringBuffer b=new StringBuffer() ;
public  InputStream in;
static  OutputStream out;
static DataInputStream Di;
static DataOutputStream Do;
//public kehu(String ip,int pot){this.ip=ip;this.pot=pot;}
public void login() throws Exception{
	Socket s=new Socket( "172.16.27.47", 9090);
	in=s.getInputStream();
	out=s.getOutputStream();
	Di=new DataInputStream(in);
	Do=new DataOutputStream(out);
	while(true){
		System.out.println("等待循环");
		js();
	}
}
public void js() throws Exception{
	System.out.print("客户端正在接受");
	int k=Di.readByte();
	if(k==0){
		int x1=Di.readInt();
		int y1=Di.readInt();
		int x2=Di.readInt();
		int y2=Di.readInt();
		ku.g.drawLine(x1, y1, x2, y2);
	}else if(k==1){
	bu=new BufferedReader(new InputStreamReader(in));
	String str=bu.readLine();
	ku.setjt1(str);
	System.out.println("设置窗体"+str);
}
}
public void run(){
	try {
		login();
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}
public static void main(String[] args) throws Exception{
	//new kehu().login("192.168.1.149", 9090);
}
}

 这是放送的方法

package First;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;

public class kejian implements ActionListener{
	public kehu k;
	public void actionPerformed(ActionEvent e) {
		// TODO Auto-generated method stub
		if(e.getActionCommand().equals("登录")){
			try {
				k=new kehu();
				k.start();
			} catch (Exception e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		}
		if(e.getActionCommand().equals("发送")){
			ku.getjt2();
			ku.setjt2();
			String st=ku.s;
			st+="\r\n";
			System.out.println(st+"-------客户端发送成功-----------");
			byte[] by=st.getBytes();
			try {
				k.Do.writeByte(1);
				k.out.write(by);
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		}
	}

}

 画板发送的方法

package First;

import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.DataInputStream;
import java.io.DataOutputStream;

public class kbj extends MouseAdapter{
	public int i=0;
	public kejian ke;
	public ku kk;
	public int  x1,x2,y1,y2;
	public kbj(ku k,kejian ke2){
		this.ke=ke2;
		this.kk=k;
	}
	
	public void mousePressed(MouseEvent e){
		x1=e.getX();
		y1=e.getY();
		
	}
	public void  mouseReleased(MouseEvent e){
		x2=e.getX();
		y2=e.getY();
		try {
			ke.k.Do.writeByte(0);
			ke.k.Do.writeInt(x1);
			ke.k.Do.writeInt(y1);
			ke.k.Do.writeInt(x2);
			ke.k.Do.writeInt(y2);
			System.out.println("发送成功");
			ke.k.Do.flush();
		} catch (Exception e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		kk.g.drawLine(x1, y1, x2, y2);
		}
		
}

 源码已经上传,不懂之处可以留言,可以联系505860922

  • 大小: 21.4 KB
  • 大小: 22.2 KB
  • 通信.zip (22.3 KB)
  • 描述: 源码
  • 下载次数: 14
2
9
分享到:
评论
3 楼 再_见孙悟空 2014-02-04  
膜拜黄大神
2 楼 lijingshou 2014-01-13  
不错...都看到有人盗版了..哈
1 楼 happinessaflower 2014-01-08  
感谢分享

相关推荐

    基于Java的趣味交互式动漫风格聊天器设计毕业论文(43页15182字数).doc

    为了更好的实现趣味性动漫风格聊天器,结合操作简单、性能稳定的目标,本论文选择的是基于C/S模型的Java聊天器在局域网内的应用与开发,使用的开发工具是Eclipse. 网络上以Java为基础实现的聊天室比比皆是,该论文的...

    修改版的java聊天器.rar_聊天器

    在原来的基础上进行修改 1.就是把接受线程放在了chat.java中了.这样在此jcreate3.x版本中就可以用了. 我是这样理解的.如果接受线程放在chatFrame中的话,在程序运行实例chatFrame对象后,得到的只是一个没接收数据前的...

    Java高手真经(编程基础卷)光盘全部源码 免积分

    javaswing.zip 18.Swing图形界面开发——Java文本编辑器 javaswt.zip 19.SWT图形界面开发——Java文本编辑器 javajface.zip 20.SWT增强组件库JFace 第5部分(5个程序包) javaapplet.zip 21.Applet网络组件——...

    java源码包---java 源码 大量 实例

     Tcp服务端与客户端的JAVA实例源代码,一个简单的Java TCP服务器端程序,别外还有一个客户端的程序,两者互相配合可以开发出超多的网络程序,这是最基础的部分。 递归遍历矩阵 1个目标文件,简单! 多人聊天室 3...

    Java高手真经(编程基础卷)光盘全部源码

    javaswing.zip 18.Swing图形界面开发——Java文本编辑器 javaswt.zip 19.SWT图形界面开发——Java文本编辑器 javajface.zip 20.SWT增强组件库JFace 第5部分(5个程序包) javaapplet.zip 21.Applet网络组件——电子...

    java源码包4

     Tcp服务端与客户端的JAVA实例源代码,一个简单的Java TCP服务器端程序,别外还有一个客户端的程序,两者互相配合可以开发出超多的网络程序,这是最基础的部分。 递归遍历矩阵 1个目标文件,简单! 多人聊天室 ...

    java编程基础,应用与实例

    16.3 布局管理器 248 16.3.1 BorderLayout类 248 16.3.2 FlowLayout类 249 16.3.3 GridLayout类 252 16.4 组件(Components) 253 16.4.1 标签(Label) 253 16.4.2 按钮(Button) 254 16.4.3 单行文本框...

    java源码包3

     Tcp服务端与客户端的JAVA实例源代码,一个简单的Java TCP服务器端程序,别外还有一个客户端的程序,两者互相配合可以开发出超多的网络程序,这是最基础的部分。 递归遍历矩阵 1个目标文件,简单! 多人聊天室 ...

    java源码包2

     Tcp服务端与客户端的JAVA实例源代码,一个简单的Java TCP服务器端程序,别外还有一个客户端的程序,两者互相配合可以开发出超多的网络程序,这是最基础的部分。 递归遍历矩阵 1个目标文件,简单! 多人聊天室 ...

    JAVA上百实例源码以及开源项目

     Tcp服务端与客户端的JAVA实例源代码,一个简单的Java TCP服务器端程序,别外还有一个客户端的程序,两者互相配合可以开发出超多的网络程序,这是最基础的部分。 递归遍历矩阵 1个目标文件,简单! 多人聊天室 3...

    JAVA上百实例源码以及开源项目源代码

     Tcp服务端与客户端的JAVA实例源代码,一个简单的Java TCP服务器端程序,别外还有一个客户端的程序,两者互相配合可以开发出超多的网络程序,这是最基础的部分。 递归遍历矩阵 1个目标文件,简单! 多人聊天室 3...

    JAVA基于局域网的聊天室系统(源代码+论文).zip

    JAVA基于局域网的聊天室系统(源代码+论文) 摘 要 视频聊天系统作为一种新型的通信和交流工具,突破了地域的限制,可以提供更为便捷、灵活、全面的音、视频信息的传递和服务,具有极其广泛的发展前景。 本文介绍了...

    Java开发技术大全(500个源代码).

    示例描述:本章介绍开发Java的基础语法知识。 accumulationByDoWhile.java 用do~while语句写的累加程序 accumulationByFor.java 用for语句写的累加程序 accumulationByWhile.java 用while语句写的累加程序 ...

    Java课程设计案例精选

    第8章 Java聊天室  8.1 功能描述  8.2 理论基础  8.3 总体设计  8.4 代码实现  8.5 程序的运行与发布 第9章 宝石连连看游戏  9.1 功能描述  9.2 总体设计  9.3 代码实现  9.4 程序的运行与发布 ...

    成百上千个Java 源码DEMO 4(1-4是独立压缩包)

    用累加器,以对话状态存储起来,创建EJB对象,并将当前的计数器初始化,调用每一个EJB对象的count()方法,保证Bean正常被激活和钝化,EJB对象是用完毕,从内存中清除…… Java Socket 聊天通信演示代码 2个目标文件...

    Java视频教程 Java游戏服务器端开发 Netty NIO AIO Mina视频教程

    三、Java语言基础教程-Java NIO流篇 [第1节] Java NIO流-简介和概述.flv [第2节] Java NIO流-缓冲区.flv [第3节] Java NIO流-缓冲区操作.flv [第4节] JavaNIO流-通道1.flv [第5节] Java NIO流-通道2.flv [第6...

    Java在线聊天系统.rar

    一、搭建服务器端 a)、创建ServerSocket对象绑定监听端口。...d)、关闭响应资源这个项目非常适合学完Java基础来练手,该项目就是对Socket网络编程、IO流、线程及线程池等知识进行一些实战综合运用。

    Java课程设计实训大作业:记事本+简易计算器+聊天系统+日历+中英查询(含源代码+运行截图+实训报告)

    1.软件界面美观、功能完善软件,导航清晰,操作方便,使用菜单栏、工具栏、布局管理器、按钮、表格等多种Java图形界面组件。 2.程序代码清晰,语法规范,结构合理,逻辑正确。 3.功能完善,程序代码优化,执行效率高...

    疯狂java实战演义 光盘源码

    本书知识点丰富,适合有一定Java基础、有意向做Java桌面应用程序或者想了解Java图形界面编程的读者阅读,也可作为Java开发程序员的案例参考书 gobang: 第1章 控制台五子棋 cal: 第2章 仿Windows计算器 viewer: ...

Global site tag (gtag.js) - Google Analytics