UDP的点对点聊天程序(swing界面)

点对点聊天的程序(swing界面)

主要代码

客户端

new Thread() {
	public void run() {
		try {
			//创建客户端的套接字
			Socket socket=new Socket("localhost",Integer.parseInt(textField_2. getText()));
			
			//获取socket通道的输入流(输出流实现读取数据一行一行的读写
			//InputStream in=socket.getInputStream();
			BufferedReader br= new BufferedReader(new InputStreamReader(socket. getInputStream()));
			String line=null;
			
			//用户点击发送按钮的时候写出
			//获取socket通道的输出流,写一行换一行
			bw= new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
			if((line=br.readLine())!=null) {
				//将读入的数据拼接到文本域中显示
				//System.lineSeparator()换行
				textArea.append(line+System.lineSeparator());
			}
			//关闭socket 通道
			socket.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}.start();

服务器端

new Thread() {
	public void run() {
		try {
			//创建客户端的套接字
			Socket socket=new Socket("localhost",Integer.parseInt(textField_2.getText()));
			
			//获取socket通道的输入流(输出流实现读取数据一行一行的读写
			//InputStream in=socket.getInputStream();
			BufferedReader br= new BufferedReader(new InputStreamReader(socket.getInputStream()));
			String line=null;
			
			//用户点击发送按钮的时候写出
			//获取socket通道的输出流,写一行换一行
			bw= new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
			if((line=br.readLine())!=null) {
				//将读入的数据拼接到文本域中显示
				//System.lineSeparator()换行
				textArea.append(line+System.lineSeparator());
			}
			
			//关闭socket 通道
			socket.close();
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}.start();

内容发送

try {
	if(textField_1.getText().equals("")||textField_2.getText().equals("")) {
		JOptionPane.showMessageDialog(test.this, "请输入接受者地址和端口号");
	}
	else if(textField.getText().equals("")) {
		JOptionPane.showMessageDialog(test.this, "发送内容不能为空");
	}else {
		textArea.append(textField_3.getText()+"(我)说:"+textField.getText()+"\n");
		bw.write(textField_3.getText()+"说:"+textField.getText());
		bw.newLine();
		bw.flush();
		textField.setText("");
	}
} catch (IOException e1) {
	// TODO Auto-generated catch block
	e1.printStackTrace();
}

问题注意

1、Connection reset

出现问题:
UDP的点对点聊天程序(swing界面)_第1张图片

自己了解到的原因是:

1)服务器的并发连接数超过了其承载量,服务器会将其中一些连接关闭;

如果知道实际连接服务器的并发客户数没有超过服务器的承载量,则有可能是中了病毒或者木马,引起网络流量异常。可以使用netstat -an查看网络连接情况。

2)客户关掉了浏览器,而服务器还在给客户端发送数据;

3)浏览器端按了Stop;

这两种情况一般不会影响服务器。但是如果对异常信息没有特别处理,有可能在服务器的日志文件中,重复出现该异常,造成服务器日志文件过大,影响服务器的运行。可以对引起异常的部分,使用try…catch捕获该异常,然后不输出或者只输出一句提示信息,避免使用e.printStackTrace();输出全部异常信息。

还有很多原因,推荐一篇博客:https://blog.51cto.com/hope1/1880049

我的原因是:服务器的并发连接数超过了其承载量

解决方案:本来客户机和 服务器都是通过while构成死循环进行具体的工作;所以我将客户机的死循环修改为完成具体操作后结束循环,问题得到解决;

2、界面加载不出来

开始的时候客户端和服务器端代码都是死循环,swing界面运行不起来;

自己最后使用线程进行具体操作;

创建线程三种方法

1.继承Thread类
优点:可以直接使用Thread类中的方法,代码比较简单。
缺点:继承Thread类之后不能继承其他类。

2.实现Runable接口
优点:实现接口,比影响继承其他类或实现接口。

3.实现Callable接口
优点:可以获取返回值,可以抛出异常。
缺点:实现方法相对复杂

//继承Thread类 
/*1.创建Thread类对象。
* 2.重写run方法,添加在线程中执行的方法。
* 3.start方法启动线程。
*/
new Thread() { 
   public void run() { 
        for(int i=0;i<100;i++) { System.out.println(i+"\n"); }
      } 
    }.start(); 
//实现Runnable接口
/*1.实现Runable接口。
* 2.重写run方法,添加在线程中执行的方法。
* 3.创建thread类对象,Runable接口的实现作为参数传入,执行带参数的构造函数。
* 4.start方法启动线程。
*/
Runnable ra= new Runnable() {
@Override
public void run() { 
   for(int i=0;i<1000;i++)
  {System.out.println("Runnable线程测试 "+i);}
   } 
};
Thread thread = new Thread(ra); 
thread.start(); 
//Callable
/*1.创建线程池。
* 2.现实Callable接口。
* 3.重写Call方法,添加在线程中执行的方法。
* 4.把Callable的实现放到线程池中。并获得线程池返回的Future对象。
*/
ExecutorService es = Executors.newFixedThreadPool(3);
Callable<Integer> ca=new Callable<Integer>() {
	@Override
	public Integer call() throws Exception {
		return 100;
	}
};
Future<Integer> ft =es.submit(ca);
System.out.println(ft.get());
es.shutdown();
}

完整代码

import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import javax.swing.JScrollPane;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.awt.event.ActionEvent;
import javax.swing.JTextArea;

public class test extends JFrame {

	private JPanel contentPane;
	private JTextField textField;
	private JTextField textField_1;
	private JTextField textField_2;
	private JTextField textField_3;
	private JTextField textField_4;
	BufferedWriter bw=null;
	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					UDPmain frame = new UDPmain();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the frame.
	 */
	public test() {
		setResizable(false);
		setTitle("UDPserver");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 602, 418);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		contentPane.setLayout(null);
		
		JLabel lblip = new JLabel("\u5BF9\u65B9IP");
		lblip.setBounds(68, 43, 58, 15);
		contentPane.add(lblip);
		
		JLabel label = new JLabel("\u7528\u6237\u540D");
		label.setBounds(68, 98, 58, 15);
		contentPane.add(label);
		
		JLabel label_1 = new JLabel("\u7AEF\u53E3\u53F7");
		label_1.setBounds(302, 43, 58, 15);
		contentPane.add(label_1);
		
		JLabel label_2 = new JLabel("\u672C\u673A\u7AEF\u53E3\u53F7");
		label_2.setBounds(302, 98, 78, 15);
		contentPane.add(label_2);
		
		JScrollPane scrollPane = new JScrollPane();
		scrollPane.setBounds(38, 130, 498, 176);
		contentPane.add(scrollPane);

		JTextArea textArea = new JTextArea();
		textArea.setEditable(false);
		scrollPane.setViewportView(textArea);
		
		textField = new JTextField();
		textField.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if(textField.getText().equals("")) {
					
				}else {
					new Thread() {
						public void run() {
							try {
								//创建客户端的套接字
								Socket socket=new Socket("localhost",Integer.parseInt(textField_2.getText()));
								
								//获取socket通道的输入流(输出流实现读取数据一行一行的读写
								//InputStream in=socket.getInputStream();
								BufferedReader br= new BufferedReader(new InputStreamReader(socket.getInputStream()));
								String line=null;
								
								//用户点击发送按钮的时候写出
								//获取socket通道的输出流,写一行换一行
								bw= new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
								if((line=br.readLine())!=null) {
									//将读入的数据拼接到文本域中显示
									//System.lineSeparator()换行
									textArea.append(line+System.lineSeparator());
								}
								
								//关闭socket 通道
								socket.close();
								
							} catch (IOException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
						}
					}.start();
				}
			}
		});
		textField.setBounds(38, 336, 364, 21);
		contentPane.add(textField);
		textField.setColumns(10);
		
		textField_1 = new JTextField();
		textField_1.setBounds(122, 40, 142, 21);
		contentPane.add(textField_1);
		textField_1.setColumns(10);
		
		textField_2 = new JTextField();
		textField_2.setBounds(370, 40, 142, 21);
		contentPane.add(textField_2);
		textField_2.setColumns(10);
		
		textField_3 = new JTextField();
		textField_3.setBounds(122, 95, 66, 21);
		contentPane.add(textField_3);
		textField_3.setColumns(10);
		
		textField_4 = new JTextField();
		textField_4.setBounds(390, 95, 122, 21);
		contentPane.add(textField_4);
		textField_4.setColumns(10);
		
		//绑定端口
		JButton button_1 = new JButton("\u7ED1\u5B9A  \u7AEF\u53E3");
		button_1.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				//禁止在输入框中输入内容
				if(textField_3.getText().trim().equals("")||textField_4.getText().trim().equals("")) {
					JOptionPane.showMessageDialog(test.this, "请输入发送者姓名和端口号");
				}else {
					textField_3.setEditable(false);
					textField_4.setEditable(false);	
					new Thread() {
						public void run() {
							try {
								//创建服务器端的套接字
								ServerSocket serverSocket=new ServerSocket(Integer.parseInt(textField_4.getText()));
								//等待客户端的连接
								Socket socket=serverSocket.accept();
								//获取socket通道的输入流(输出流实现读取数据)
								//InputStream in=socket.getInputStream();
								BufferedReader br= new BufferedReader(new InputStreamReader(socket.getInputStream()));
								//获取socket通道的输出流,写一行换一行
								//用户点击发送按钮的时候写出
								bw= new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
								String line=null;
								while((line=br.readLine())!=null) {
									//将读入的数据拼接到文本域中显示
									textArea.append(line+System.lineSeparator());
								}
								
								//关闭socket 通道
								serverSocket.close();
								
							} catch (IOException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
						}
					}.start();
				}
			}
		});
		button_1.setBounds(195, 94, 97, 23);
		contentPane.add(button_1);
		
		//发送
		JButton button = new JButton("\u53D1\u9001");
		button.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				try {
					if(textField_1.getText().equals("")||textField_2.getText().equals("")) {
						JOptionPane.showMessageDialog(test.this, "请输入接受者地址和端口号");
					}
					else if(textField.getText().equals("")) {
						JOptionPane.showMessageDialog(test.this, "发送内容不能为空");
					}else {
						textArea.append(textField_3.getText()+"(我)说:"+textField.getText()+"\n");
						bw.write(textField_3.getText()+"说:"+textField.getText());
						bw.newLine();
						bw.flush();
						textField.setText("");
					}
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}		
				
			}
		});
		button.setBounds(436, 335, 97, 23);
		contentPane.add(button);
	}
}


结果展示

UDP的点对点聊天程序(swing界面)_第2张图片

你可能感兴趣的:(java知识)