【问题标题】:"java.net.SocketException: socket closed" while binding a UDP socket绑定 UDP 套接字时出现“java.net.SocketException:套接字已关闭”
【发布时间】:2014-02-25 02:43:38
【问题描述】:

我正在尝试开发一个简单的 UDP 连接,并且是这种编程类型的新手。我试图开发的是在客户端和服务器之间建立连接。首先,我从客户端发送数据。它将按原样到达服务器,并且工作正常。然后服务器将相同的数据转换成大写后返回给客户端,它也到达客户端。但是现在每次按下按钮时都会收到“SocketException”。我将在下面提供我的代码。

这是服务器代码:

import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;

public class ServerUDP extends JFrame implements ActionListener
{

Label l1;
Button b1;
DatagramSocket ds=null;
String st;

public ServerUDP()
{
setLayout(null);
setSize(300,300);
setLocation(50,50);
setTitle("Server Side");
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);

b1=new Button("SEND TO CLIENT");
b1.setBounds(30,70,200,30);
add(b1);
b1.addActionListener(this);

l1=new Label();
l1.setBounds(30,110,150,30);
add(l1);

while(true)
{
  conn();
}
}

public void connect()
{
 try
{
  ds=new DatagramSocket();
  InetAddress ip=InetAddress.getByName("localhost");
  byte[] b1=new byte[st.length()];
  b1=st.getBytes();
  DatagramPacket dp=new DatagramPacket(b1,st.length(),ip,9999);
  ds.send(dp);
  ds.close();
}
catch(Exception e)
{
  System.out.println("Error 1 = "+e);
}
}

public void actionPerformed(ActionEvent ae)
{
if(ae.getSource()==b1)
{
  st=l1.getText();
  connect();
  l1.setText("");
  if(st.equals("bye"))
  {
    dispose();
  }
}
}

public void conn()
{
try
{
  ds=new DatagramSocket(6666);
  byte[] b1=new byte[1024];
  DatagramPacket dp=new DatagramPacket(b1,b1.length);
  ds.receive(dp);
  st=new String(dp.getData(),0,dp.getLength());
  l1.setText(st.toUpperCase());
  ds.close();
}
catch(Exception e)
{
  System.out.println("Error 2 = "+e);
}
}

public static void main(String[] ar)
{
ServerUDP c=new ServerUDP();
}
}

这是客户端代码:

import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;

public class ClientUDP extends JFrame implements ActionListener
{

TextField t1;
Label l1,l2;
Button b1;
DatagramSocket ds=null;
String st;

public ClientUDP()
{
setLayout(null);
setSize(300,300);
setLocation(400,50);
setTitle("Client Side");
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);

l2=new Label("Enter Message : ");
l2.setBounds(10,20,100,30);
add(l2);

t1=new TextField();
t1.setBounds(120,20,150,30);
add(t1);

b1=new Button("SEND TO SERVER");
b1.setBounds(70,70,200,30);
add(b1);
b1.addActionListener(this);

l1=new Label();
l1.setBounds(30,110,150,30);
add(l1);

while(true)
{
  connect();
}
}

public void connect()
{
try
{
  ds=new DatagramSocket(9999);
  byte[] b1=new byte[1024];
  DatagramPacket dp=new DatagramPacket(b1,b1.length);
  ds.receive(dp);
  st=new String(dp.getData(),0,dp.getLength());
  l1.setText(st);
  ds.close();
}
catch(Exception e)
{
  System.out.println("Error 3 = "+e);
}
}

public void actionPerformed(ActionEvent ae)
{
if(ae.getSource()==b1)
{
  st=t1.getText();
  con(st);
  t1.setText("");
  if(st.equals("bye"))
  {
    dispose();
  }
}
}

public void con(String s)
{
try
{
  ds=new DatagramSocket();
  InetAddress ip=InetAddress.getByName("localhost");
  byte[] b1=new byte[s.length()];
  b1=s.getBytes();
  DatagramPacket dp=new DatagramPacket(b1,s.length(),ip,6666);
  ds.send(dp);
  ds.close();
}
catch(Exception e)
{
  System.out.println("Error 4 ="+e);
}
}

public static void main(String[] ar)
{
ClientUDP c=new ClientUDP();
}
}

我该如何解决这个异常?

【问题讨论】:

  • 你不需要不断地创建和关闭DatagramSockets.这就是问题的一半。您只需要一个用于服务器和一个用于客户端,并且它们可以在每种情况下存在于程序的整个生命周期中。您也不需要将客户端套接字绑定到任何特定端口。服务器应该回复它收到的任何数据报中包含的源地址。

标签: java sockets udp udpclient


【解决方案1】:

当您正在使用的端口已被某个应用程序使用(可能被您自己的应用程序在某个循环中使用)时,会发生此异常

检查端口 6666 和 9999 是否被其他应用程序使用。

【讨论】:

  • 还有一个问题。发送和接收数据只能在服务器端和客户端进行一次。多次发送和接收数据应该怎么做。
  • 当您对关闭的套接字执行任何操作时会发生此异常。您描述的情况引发BindException
最近更新 更多