Java之Socket客户端间通信(JFrame版)

窗体版本的聊天室

思路与“dos版”相似,此版本是通过Runnable接口完成。
在程序开发中只要是多线程肯定永远以实现Runnable接口为主,因为实现Runnable接口相比继承Thread类有如下好处:

  • 避免点继承的局限,一个类可以继承多个接口
  • 适合于资源的共享
    一、首先创建一个JFrame类
    实现窗体输入输出流
package com.xiaogao1;
/*
 * Frame类
 */
import java.awt.FlowLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

public class FrameFather {

		JFrame jf=new JFrame();
		JTextArea jta=new JTextArea(10, 15);
		JScrollPane jsp=new JScrollPane(jta);
		JTextField jtf=new JTextField(20);
		JButton jb=new JButton("Send");
		public FrameFather()
		{
			jf.setVisible(true);
			jf.setBounds(100, 100, 300, 300);
			jf.setLayout(new FlowLayout());
			jta.setLineWrap(true); //设置会换行。
			jf.add(jsp);
			jf.add(jtf);
			jf.add(jb);
			jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		}
}

二、然后创建服务端,转发信息
通过实现Runnable接口,开启多线程无限读取信息

package com.xiaogao1;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
/*
 * 服务器
 */
public class ServerFrame extends FrameFather implements Runnable{
	ServerSocket server;
	Socket client;
	OutputStream os;
	InputStream is;
	//点击按钮就发信息,另外开启一个线程来不停读消息
	public ServerFrame()
	{
		jb.addActionListener(new ActionListener() {			
			@Override
			public void actionPerformed(ActionEvent arg0) {
				try {
					os.write(jtf.getText().getBytes());
					os.flush();
					jta.append("服务器说:"+jtf.getText());
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
			}
		});
	}
	public ServerFrame(String message){
		this();
		jf.setTitle("服务器");
		
	}
	public static void main(String[] args) {
		ServerFrame fs=new ServerFrame("服务器");
		fs.init();
		new Thread(fs).start();  //开启线程,执行run方法中的内容

	}
	// 启动服务器  获得客户端的输入流和输出流
	private void init() {
		try {
			server=new ServerSocket(7788);
			client=server.accept();
			jta.append("有客户端连接成功"+client.getInetAddress().getHostAddress());
			os=client.getOutputStream();
			is=client.getInputStream();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	//开启线程的目的是为了读消息    而且是不停地读
	@Override
	public void run() {
		while(true){
			byte b[]=new byte[2*1024];
			try {
				int len=is.read(b);
				String message=new String(b,0,len);
				jta.append("客户端发来的:"+message);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		}
		
	}

}

三、最后还是创建客户端,发送信息
也是实现Runnable接口,开启多线程无限读取信息

package cn.aa;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
/*
 * 客户端
 */
public class FrameClient extends FrameFather implements Runnable{
	Socket client;
	InputStream is;
	OutputStream os;
	//写消息给服务器 
	public FrameClient() {
		jb.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent arg0) {
				try {
					os.write(jtf.getText().getBytes());
					os.flush();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
			}
		});
	}
	public FrameClient(String name) {
		this();
		jf.setTitle(name);
	}



	public static void main(String[] args) {
		//启动连接 
		FrameClient fc=new FrameClient("客户端");
		fc.init();
		new Thread(fc).start();

	}

	//连接到服务器去
	private void init() {
		try {
			client=new Socket("127.0.0.1", 7788);
			os=client.getOutputStream();
			is=client.getInputStream();
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	@Override
	public void run() {
		while(true){
			byte []b=new byte[10*1024];
			try {
				int len=is.read(b);
				jta.append("服务器说:"+new String(b,0,len));
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		}
		
	}

}

你可能感兴趣的:(聊天室,多线程,开发设计,输入输出流)