`

java 通信

阅读更多
                                                 通信学习
学习通信,从兴趣开始,之前我也尝试过自己弄一个C++的通信,买了相关的书籍,一步一步的做下去,开始时做的还有模有样,实现了基本的对话功能,但是后来,当我想实现更多功能时,发现自己编变得无从下手,第一是因为书籍问题(已知没有找到关于通信的系统的书籍),第二是我对C++的编程习惯不感冒,于是我就走向了java的通信设计中去。
首先,明确目标:做一个既可以对话又可以发图片(当然是可以群聊的)的聊天系统;
再来便是明确实施步骤,1.先是做个服务端,可以先让电脑上的telnet来充当客户端,能实现Eclipse的控制台与telnet对话;2.做个客户端界面,不必做的太过于复杂,有输入和显示功能即可,也就是相当于把这个客户端当做telnet实现对话;3.利用线程来实现多个客户端的对话;4.实现发送图片等功能,并可以自己加上自己喜欢的功能!好了,说了那么多,接下来就请看代码:

这是服务端代码,用于开启服务器
package 通信聊天;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
	//0-65535
	public void setup(int port){
		//服务器套接字
		try {
			ServerSocket ss = new ServerSocket(port);
			System.out.println("监听端口"+port+"成功!");
			
			while(true){
				//阻塞
				Socket socket = ss.accept();
				System.out.println("有人访问了");
			
				ServerThread st = new ServerThread(socket);
				st.start();
			}
			
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		new Server().setup(8888);
	}

}

这是服务器的线程,实现数据的传输
package 通信聊天;

import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
import java.util.ArrayList;

public class ServerThread extends Thread {
	//保存所有客户端的线程
	private static ArrayList<ServerThread> list = new ArrayList<ServerThread>();
	private Socket socket;
	private String name;
	private OutputStream output;
	private DataOutputStream dos;
	
	public ServerThread(Socket socket){
		this.socket = socket;
		list.add(this);
	}

	public void run(){
		try {
			InputStream input = socket.getInputStream();
			output = socket.getOutputStream();
			dos = new DataOutputStream(output);
			
			//向客户端发送信息
			String str = "请输入您的名字:\r\n";
			sendMsg(str);
			
			name = readLine(input);
			//数据流
			DataInputStream  dis = new DataInputStream(input);
			
			while(true){

				
				int type = dis.readInt();
				if(type == 1){
					//接收数据包的长度
					int len = dis.readInt();
					//接收数据包内容的数组
					byte[] bytes = new byte[len];
					//把读到的数据填到bytes里面
					dis.readFully(bytes);
					
					String line = new String(bytes,"GBK");
					System.out.println("Recv:"+line);
					
					//向所有的客户端广播信息
					for(int i=0; i<list.size(); i++){
						ServerThread st = list.get(i);

						st.sendMsg(name+"说:"+line);
					}
				} else if(type == 2){
					//接收线条
					int len = dis.readInt();
					int x1 = dis.readInt();
					int y1 = dis.readInt();
					int x2 = dis.readInt();
					int y2 = dis.readInt();
					
					for(int i=0; i<list.size(); i++){
						ServerThread st = list.get(i);
						
						st.dos.writeInt(2);
						st.dos.writeInt(len);
						st.dos.writeInt(x1);
						st.dos.writeInt(y1);
						st.dos.writeInt(x2);
						st.dos.writeInt(y2);
					}
				} else if(type == 3){
					//接收图片
					int len = dis.readInt();
					byte[] bytes  = new byte[len];
					dis.readFully(bytes);
					System.out.println("Server recvpic "+bytes.length);
					//
					for(int i=0; i<list.size(); i++){
						ServerThread st = list.get(i);

						st.dos.writeInt(3);
						st.dos.writeInt(len);
						st.dos.write(bytes);
					}
				}
			}
		} catch (Exception ex){
			ex.printStackTrace();
		}
	}
	
	public void sendMsg(String str) throws IOException{
		str += "\r\n";
		byte[] bytes = str.getBytes("GBK");
		int len = bytes.length;
		
		//发送消息包的类型:1.文本,2.文件,3.图片
		dos.writeInt(1);
		//先发送数据的长度
		dos.writeInt(len);
		//再发送数据内容
		dos.write(bytes);
		

	}
	
	public String readLine(InputStream input) throws IOException{
		//字节队列
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		while(true){
			int n = input.read();
			if(n == '\r')
				continue;
			if(n == '\n'){
				break;
			}
			//把每一个字节存入队列
			bos.write(n);
		}
		byte[] bytes = bos.toByteArray();
		//把字节还原成字符串
		String content = new String(bytes, "GBK");
		return content;
	}
}

这是客户端代码,用于设计界面和实现功能
package 客户端;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;

public class Client implements MsgListener{
	private JTextPane log2 ;
	public JPanel jpa;
	private Document doc; 
	ClientThread ct = new ClientThread();
	final JFrame jf = new JFrame("QQ聊天");
	
	public void initUI(){
		
		jf.setDefaultCloseOperation(3);
		jf.setLocation(100, 100);
		jf.setLayout(new FlowLayout());
		jf.setResizable(false);
		jf.setSize(900, 500);
		
		//放置图片的地方
		log2 = new JTextPane();
		JScrollPane js2 =new JScrollPane(log2);
		log2.setEditable(false);
		log2.setPreferredSize( new Dimension(860,180));
		doc = log2.getDocument();
		jf.add(js2);
		final JTextField input = new JTextField(65);
		jf.add(input);
		jpa =new JPanel();
		
		jpa.setPreferredSize(new Dimension(860,230));
		jpa.setBackground(Color.PINK);
		JButton btn = new JButton("Send");
		jf.add(btn);
		JButton btn0 = new JButton("Pic");
		jf.add(btn0);
		JLabel jla = new JLabel("绘图区");
		jpa.add(jla);
		jf.add(jpa);
		
		jf.setVisible(true);
		jf.addMouseListener(ma);
		jpa.addMouseListener(ma);
		jpa.addMouseMotionListener(ma);
		
		
		ct.addMsgListener(this);
		ct.start();
		btn.addActionListener(new ActionListener(){

			public void actionPerformed(ActionEvent e) {
				String msg = input.getText();
				input.setText("");
				try {
					ct.sendMsg(msg);
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}
			
		});
		
		btn0.addActionListener(new ActionListener() {
			
			public void actionPerformed(ActionEvent e) {
				
				JFileChooser jc = new JFileChooser();
				jc.showOpenDialog(jf);
				
				File file = jc.getSelectedFile();
				try {
					
					FileInputStream fis = new FileInputStream(file);
					
					byte[] bytes = new byte[fis.available()];
					
					fis.read(bytes);
					fis.close();
					
					ct.sendImg(bytes);
				} catch (Exception e1) {
					e1.printStackTrace();
				}
			}
		});
		
		
		

	}
	

	
	MouseAdapter ma = new MouseAdapter() {
		int x1,x2,y1,y2;
		 public void mousePressed(MouseEvent e) {
			 x1 = e.getX();
			 y1 = e.getY();
		 }

		 public void mouseReleased(MouseEvent e) {
			 x2 = e.getX();
			 y2 = e.getY();
			 
			 try {
				 //把线条的两个点发送到服务器
				ct.sendLine(x1, y1, x2, y2);
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		 }
		 
		 public void mouseDragged(MouseEvent e){
			 x2 = e.getX();
			 y2 = e.getY();
			 
			 try {
				 //把线条的两个点发送到服务器
				ct.sendLine(x1, y1, x2, y2);
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			 
			 x1 = x2;
			 y1 = y2;
		 }
		 
	};

	public static void main(String[] args) {
		new Client().initUI();
	}
	public void onRecvMsg(String msg){
		Document doc = log2.getDocument();
		try {
			doc.insertString(doc.getLength(), msg+"\r\n", null);
		} catch (BadLocationException e) {
			e.printStackTrace();
		}
		
		//log.append(msg+"\r\n");
	}
	public void onRecvLine(int x1, int y1, int x2, int y2) {
		jpa.getGraphics().drawLine(x1, y1, x2, y2);
	}
	public void onRecvPic(byte[] bytes) {
		ByteArrayInputStream input = new ByteArrayInputStream(bytes);
		
		try {
			BufferedImage img = ImageIO.read(input);
			
			ImageIcon icon = new ImageIcon(img);
			
			log2.setCaretPosition(doc.getLength());
			log2.insertIcon(icon);
			
			Document doc = log2.getDocument();
			try {
				doc.insertString(doc.getLength(), "\r\n", null);
			} catch (BadLocationException e) {
				e.printStackTrace();
			}
			
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}

这是客户端线程代码
package 客户端;

import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.ArrayList;

public class ClientThread extends Thread {
	private OutputStream output;
	DataOutputStream dos;
	private ArrayList<MsgListener> list = new ArrayList<MsgListener>();

	public void addMsgListener(MsgListener listener){
		list.add(listener);
	}
	
	}
	
	public void sendLine(int x1,int y1,int x2,int y2) throws IOException{
		dos.writeInt(2);
		int len = 16;
		dos.writeInt(len);
		
		dos.writeInt(x1);
		dos.writeInt(y1);
		dos.writeInt(x2);
		dos.writeInt(y2);
	}
	
	public void sendImg(byte[] bytes) throws IOException{
		dos.writeInt(3);
		
		dos.writeInt(bytes.length);
		//再发送数据内容
		dos.write(bytes);
	}
	
	public void sendMsg(String str) throws IOException{
		str += "\r\n";
		byte[] bytes = str.getBytes("GBK");
		int len = bytes.length;
		
		//发送消息包的类型:1.文本,2.线条,3.图片
		dos.writeInt(1);
		//先发送数据的长度
		dos.writeInt(len);
		//再发送数据内容
		dos.write(bytes);
		
	}
	}

	public void run(){
		try {
			Socket socket = new Socket("127.0.0.1", 8888);
			
			InputStream input = socket.getInputStream();
			output = socket.getOutputStream();
			dos = new DataOutputStream(output);
			DataInputStream dis = new DataInputStream(input);
			
			while(true){
				int type = dis.readInt();
				if(type == 1){
					//接收数据包的长度
					int len = dis.readInt();
					//接收数据包内容的数组
					byte[] bytes = new byte[len];
					//把读到的数据填到bytes里面
					dis.readFully(bytes);
					
					String line = new String(bytes,"GBK");
					
					for(int i=0; i<list.size(); i++){
						list.get(i).onRecvMsg(line);
					}
				} else if(type == 2){
					//接收线条
					int len = dis.readInt();
					int x1 = dis.readInt();
					int y1 = dis.readInt();
					int x2 = dis.readInt();
					int y2 = dis.readInt();
					
					for(int i=0; i<list.size(); i++){
						list.get(i).onRecvLine(x1, y1, x2, y2);
					}
				}else if(type == 3){
					//接收图片
					int len = dis.readInt();
					byte[] bytes = new byte[len];
					//把读到的数据填到bytes里面
					dis.readFully(bytes);
					//
					for(int i=0; i<list.size(); i++){
						 list.get(i).onRecvPic(bytes);
						
					}
				}
				
				
					listener.onRecvMsg(line);
			}
			
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public String readLine(InputStream input) throws IOException{
		//字节数组队列
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		while(true){
			int n = input.read();
			if(n == '\r')
				continue;
			if(n == '\n'){
				break;
			}
			//把收到的字节存到队列中
			bos.write(n);
		}
		byte[] bytes = bos.toByteArray();
		String content = new String(bytes, "GBK");
		return content;
	}
}


这是客户端接口代码
package 客户端;

public interface MsgListener {
	
	public void onRecvMsg(String msg);
	
	public void onRecvLine(int x1,int y1,int x2,int y2);
	
	public void onRecvPic(byte[] bytes);
}
[img]

最后,总结一下,每个人都会犯错误,我也一样,本程序中,在你打开客户端界面时,必须得先输入名字,若是手一抖先绘图了,程序就会报错哦。本次通信未能实现文件传输功能,现在上传主要是为了方便通信新手来观看,指导,如果有错误,欢迎留言!!最后喝杯茶来结束我今天的技术博客报告
  • 大小: 15.3 KB
分享到:
评论

相关推荐

    flex与java通信

    Flex与Java通信是Web开发中的一个重要领域,它允许前端用户界面(UI)通过富互联网应用程序(RIA)与后端服务器进行交互。Flex是Adobe开发的一种用于构建动态、交互性强的Web应用的开源框架,主要基于ActionScript...

    java通信学习-协议与加密

    在IT行业中,Java通信学习是开发者必须掌握的重要技能之一,特别是在构建分布式系统、网络应用或者进行数据传输时。本篇文章将聚焦于“协议与加密”这两个核心概念,它们是Java通信中的基石。以下是对这两个主题的...

    java通信录

    Java 通信录小程序设计 Java 通信录小程序是基于 Java 语言开发的一款通讯录软件,该程序可以帮助初学者更好地了解 Java 编程的基本原理和编写方法。在本资源中,我们将详细介绍 Java 通信录小程序的设计和实现过程...

    java读写Modbus RTU数据,java串口modbus通信,Modbus RTU与java通信 全开源

    最近在研究处理java写modbus RTU通信,分别使用几套工具,模拟modbus从站、模拟串口等才能正常在电脑测试成功。 全开源,放心下载 可以查看运行内容https://blog.csdn.net/weijia3624/article/details/121216539

    flex与java通信的完整demo

    Flex与Java通信是Web开发中的一个重要技术组合,它允许用户在浏览器端利用Flash的富互联网应用(RIA)特性,通过ActionScript与服务器端的Java应用程序进行数据交互。本压缩包包含了一个完整的Flex与Java通信的示例...

    java通信参考程序

    "java通信参考程序"是一个专为学习和理解Java通信机制而设计的实验项目。这个实验程序旨在帮助初学者和开发者了解如何在Java环境中实现不同节点之间的数据交换,这对于构建分布式系统、网络服务或客户端应用至关重要...

    最简单的BlazeDS实现flex与java通信.rtf

    最简单的BlazeDS实现flex与java通信..无积分下载...最简单的BlazeDS实现flex与java通信..无积分下载...最简单的BlazeDS实现flex与java通信..无积分下载...最简单的BlazeDS实现flex与java通信..无积分下载...最简单的...

    flash+java通信例子

    本示例“Flash+Java通信例子”聚焦于如何利用Adobe Flash与Java应用程序之间进行数据交互。这两种技术结合,可以为用户提供丰富的交互式Web体验,特别是在多媒体、游戏和动态内容展示方面。 Flash是一款广泛应用于...

    java读写Modbus TCP UDP数据,java与modbus通信,Modbus TCP UDP与java通信 全开源

    java读写Modbus TCP UDP数据,java与modbus通信,Modbus TCP UDP与java通信 全开源 这是一个能正常通过Modbus TCP UDP协议读写项目 请放心下载,完全开源,在多个项目中已经使用

    Flex Java通信实例

    Flex Java通信实例主要探讨的是如何在Adobe Flex前端应用与Java后端服务器之间建立通信机制,以便实现数据交换和功能交互。Flex是一种开放源代码的框架,用于构建具有丰富用户界面的Web应用程序,而Java作为多平台...

    flex3 java 通信

    5. **Flash Remoting**:虽然不是Flex3与Java通信的首选方式,但Flash Remoting(通过NetConnection和NetStream类)仍然可用于与服务器端进行实时数据交换,不过它通常用于Flash Player而不是Flex。 6. **Security*...

    java通信代码大全

    Java通信代码大全主要涵盖的是如何在Java环境中实现各种网络通信技术。这涉及到一系列的技术和概念,包括TCP/IP协议、套接字编程、多线程、数据序列化等。以下是关于这些知识点的详细说明: 1. **TCP/IP协议**:TCP...

    JAVA通信协议框架Darks Codec 1.0.3

    它支持将JAVA对象与绝大部分基于字节的消息协议之间进行互相转换,以此协助开发人员便捷有效的快速构建消息协议,并为粘包、断包等问题提供了有效的解决方案。它能让开发人员从消息协议的实现中解脱出来,让其更多的...

    UnSigCom.rar_JAVA 通信_java 加密

    1. **Java通信**:Java提供了多种方式进行通信,包括但不限于RMI(远程方法调用)、JMS(Java消息服务)、Socket编程以及NIO(非阻塞I/O)。在给定的描述中,提到了“基于java的认证程序”,这可能涉及到使用Socket...

    Flex与java通信源码

    Flex与Java通信是Web开发中的一个重要技术领域,它允许用户在浏览器端通过Flex客户端与后端Java服务器进行数据交互,实现动态、富交互性的应用程序。本源码可能包含了一个示例项目,展示了如何使用Flex与Java进行...

    java通信入门学习

    【Java通信入门学习】 在Java编程中,通信是软件系统中的关键部分,它涉及不同程序、进程或系统之间的数据交换。本教程将带你逐步了解Java通信的基础知识,适合初学者入门。通过4天的学习,你将掌握如何在Java中...

    一个合适于JAVA初学者的JAVA通信

    Java通信技术是Java编程中的重要组成部分,尤其对于初学者来说,理解如何在不同的Java程序之间交换数据至关重要。这篇博文“一个合适于JAVA初学者的JAVA通信”可能涵盖了基础的网络编程概念,如套接字(Socket)编程...

Global site tag (gtag.js) - Google Analytics