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)服务器的并发连接数超过了其承载量,服务器会将其中一些连接关闭;
如果知道实际连接服务器的并发客户数没有超过服务器的承载量,则有可能是中了病毒或者木马,引起网络流量异常。可以使用netstat -an查看网络连接情况。
2)客户关掉了浏览器,而服务器还在给客户端发送数据;
3)浏览器端按了Stop;
这两种情况一般不会影响服务器。但是如果对异常信息没有特别处理,有可能在服务器的日志文件中,重复出现该异常,造成服务器日志文件过大,影响服务器的运行。可以对引起异常的部分,使用try…catch捕获该异常,然后不输出或者只输出一句提示信息,避免使用e.printStackTrace();输出全部异常信息。
还有很多原因,推荐一篇博客:https://blog.51cto.com/hope1/1880049
我的原因是:服务器的并发连接数超过了其承载量
解决方案:本来客户机和 服务器都是通过while构成死循环进行具体的工作;所以我将客户机的死循环修改为完成具体操作后结束循环,问题得到解决;
开始的时候客户端和服务器端代码都是死循环,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);
}
}