大家就先将其看待成一个中间程序。接收客户机的套接字,然后将客户机的套接字发送到服务器端,服务器端返回到中间程序,中间程序再返回给客户机。整个程序可以理解成这样,可能代码有点垃圾,还请不要见谅:客户机
↓↑
中间程序
↓↑
服务器程序下面我上代码:
本类主要负责监听套接字的接收,并起到服务器线程package com.word.socket_test;import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;public class BossSocketInterfaces implements Runnable
{
static ServerSocket ss;
public static void main(String[] args) 
{
Thread t1 = new Thread(new BossServerce());
Thread t2 = new Thread(new BossSocketInterfaces());

t2.start();
t1.start();

while(true)
{
try 
{
Socket sock = new Socket("127.0.0.1",10001);
DataOutputStream dos = new DataOutputStream(sock.getOutputStream());
dos.write(new byte[50]);

catch (UnknownHostException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}  catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try 
{
Thread.sleep(1000);

catch (InterruptedException e) 
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void run()
{
int ii = 0;
System.out.println("监听套接字线程启动---------------");
try {
ss = new ServerSocket(10001);
while(true)
{
Socket socket = ss.accept();
if(socket!=null)
{
if("127.0.0.1".equals(socket.getLocalAddress().getHostAddress()))
{
System.out.println("建立连接............");
DataInputStream dis = new DataInputStream(socket.getInputStream());
SocketThread st = new SocketThread();
st.setDis(dis);
st.setSk(socket);
st.setBossSocket();

Thread t = new Thread(st);
ii++;
t.setName("线程"+(ii)+"号");
t.start();
}
else
{
socket.close();
}
}
try {
System.out.println(ii);
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
}上面如果 监听到了套接字,将会转到这个线程来处理。
package com.word.socket_test;import java.io.DataInputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;public class SocketThread implements Runnable
{
static final String BOSSIP ="127.0.0.1";
static final int BOSSPORT = 10001;
private DataInputStream dis;
private Socket sk;
private Socket bossSocket;
public Socket getBossSocket() {
return bossSocket;
}
public void setBossSocket() {
try {
this.bossSocket = new Socket(BOSSIP,BOSSPORT);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
int i = 0;
public void run() 
{
System.out.println("处理套接字线程启动");
byte [] aa = new byte[2048];
try 
{
int len = this.dis.read(aa);
System.out.println("套接字内容实际长度:"+len);
System.out.println("套接字端口:"+this.getSk().getLocalPort());
try 
{
byte [] bb = new byte[len];
System.arraycopy(aa, 0, bb, 0, len);
Socket bosssk = new Socket("127.0.0.1",9013);
bosssk.getOutputStream().write(bb);
System.out.println("套接字已发送");
Thread.sleep(500);
System.out.println("IP为:"+this.getSk().getInetAddress().getHostAddress()+"端口为:"+this.getSk().getLocalPort()+"的Socket已经关闭");
this.getSk().close();


catch (IOException e) 
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}

catch (IOException e) 
{
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"结束");

}
public DataInputStream getDis() {
return dis;
}
public void setDis(DataInputStream dis) {
this.dis = dis;
}
public Socket getSk() {
return sk;
}
public void setSk(Socket sk) 
{
this.sk = sk;
}

}
然后将从客户机上接收到得套接字转到服务器package com.word.socket_test;import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;public class BossServerce implements Runnable
{ public void run() 
{
System.out.println("boss端线程已启动");
ServerSocket bossSocket = null;
try
{
bossSocket = new ServerSocket(9013);

catch (IOException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
while(true)
{
try 
{

Socket userSocket = bossSocket.accept();
if(userSocket!=null)
{
byte[] inputbyte = new byte[2048];
if(userSocket.getInputStream().read(inputbyte)==50)
{
System.out.println("boss端已接收到请求");
userSocket.close();
System.out.println("boss端套接字已关闭");
}
}
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

}

解决方案 »

  1.   

    对了,这是控制台的输出:
    boss端线程已启动
    监听套接字线程启动---------------
    建立连接............
    1
    处理套接字线程启动
    套接字内容实际长度:50
    套接字端口:10001
    套接字已发送
    boss端已接收到请求
    boss端套接字已关闭
    IP为:127.0.0.1端口为:10001的Socket已经关闭
    线程1号结束
    建立连接............
    2
    处理套接字线程启动
    建立连接............
    3
    处理套接字线程启动
    套接字内容实际长度:50
    套接字端口:10001
    boss端已接收到请求
    boss端套接字已关闭
    套接字已发送
    IP为:127.0.0.1端口为:10001的Socket已经关闭
    线程3号结束
    建立连接............
    4
    处理套接字线程启动
    建立连接............
    5
    处理套接字线程启动
    套接字内容实际长度:50
    套接字端口:10001
    boss端已接收到请求
    boss端套接字已关闭
    套接字已发送
    IP为:127.0.0.1端口为:10001的Socket已经关闭
    线程5号结束然后到后面某一时....
    java.net.SocketException: Connection reset by peer: socket write error
    at java.net.SocketOutputStream.socketWrite0(Native Method)
    at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92)
    at java.net.SocketOutputStream.write(SocketOutputStream.java:136)
    at java.io.DataOutputStream.write(DataOutputStream.java:90)
    at java.io.FilterOutputStream.write(FilterOutputStream.java:80)
    at com.word.socket_test.BossSocketInterfaces.main(BossSocketInterfaces.java:28)
    建立连接............
    51
    处理套接字线程启动
    套接字内容实际长度:50
    套接字端口:10001
    boss端已接收到请求
    boss端套接字已关闭
    套接字已发送
    IP为:127.0.0.1端口为:10001的Socket已经关闭
    线程51号结束
    java.net.SocketException: Connection reset by peer: socket write error
    at java.net.SocketOutputStream.socketWrite0(Native Method)
    at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92)
    at java.net.SocketOutputStream.write(SocketOutputStream.java:136)
    at java.io.DataOutputStream.write(DataOutputStream.java:90)
    at java.io.FilterOutputStream.write(FilterOutputStream.java:80)
    at com.word.socket_test.BossSocketInterfaces.main(BossSocketInterfaces.java:28)
    建立连接............
    52
    处理套接字线程启动
    java.net.SocketException: Connection reset by peer: socket write error
    at java.net.SocketOutputStream.socketWrite0(Native Method)
    at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92)
    at java.net.SocketOutputStream.write(SocketOutputStream.java:136)
    at java.io.DataOutputStream.write(DataOutputStream.java:90)
    at java.io.FilterOutputStream.write(FilterOutputStream.java:80)
    at com.word.socket_test.BossSocketInterfaces.main(BossSocketInterfaces.java:28)
    建立连接............
    53
    处理套接字线程启动
    套接字内容实际长度:50
    套接字端口:10001
    boss端已接收到请求
    boss端套接字已关闭
    套接字已发送
    IP为:127.0.0.1端口为:10001的Socket已经关闭
    线程53号结束
    java.net.SocketException: Connection reset by peer: socket write error
    at java.net.SocketOutputStream.socketWrite0(Native Method)
    at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92)
    at java.net.SocketOutputStream.write(SocketOutputStream.java:136)
    at java.io.DataOutputStream.write(DataOutputStream.java:90)
    at java.io.FilterOutputStream.write(FilterOutputStream.java:80)
    at com.word.socket_test.BossSocketInterfaces.main(BossSocketInterfaces.java:28)
    建立连接............
    54
      

  2.   

    貌似服务器线程已经关闭,致使连接服务器失败。
    socket.close();在某个时候被执行。
    粗粗看了下代码:Socket socket = ss.accept();会收到非楼主期望的字符,以使socket.close()执行。建议在Socket socket = ss.accept();后打印。另线程与网络需要小心,并考虑好每一详细步骤。
      

  3.   


    额...恕在下愚钝...不怎么明白,我唯一想到得就是,再我还没有网输出流里放东西的时候,线程就运行到this.getSk().close();把socket给关闭了,但是如果没有输出的话,那前面的长度是怎么输出来的啊?
      

  4.   

    Thread t1 = new Thread(new BossServerce());
    Thread t2 = new Thread(new BossSocketInterfaces());
            
    t2.start();
    t1.start();这两个线程 没有优先级  , 谁先执行的话,得看CPU时间片的分配,
    我也只是略看下楼主的代码,可能是这有点问题
      

  5.   

    现在我问题基本找到了,就我检测到得原因进行分析,ServerSocket里存在Socket队列,然后理论(?)上应该是从ServerSocket里accept()一个Socket出来,那个Socket就应该从ServerSocket里面消失,但是现在的情况就是Socket从ServerSocet里accept()出来后,它还存在在ServerSocket里,而accept()是在一个循环里,于是取一个Socket就启一个处理该Socket的线程,然后就有可能出现,该Socket的关闭时间控制不到,于是当dos.write(new byte[50]);的时候,就有可能发生悲剧...我只是猜测,猜测...
      

  6.   

    楼主在Socket socket = ss.accept();这行代码后打印输出收到的字符。就可以观察到收到了什么字符。按楼主代码,
    “但是现在的情况就是Socket从ServerSocet里accept()出来”
    的确应该存在,但影响不大。我的意思是:关闭连接的是BossSocketInterfaces中的以使socket.close().
      

  7.   


    您的意思是说在ss.accept();之后System.out.println(socket.getInputStream().read(new byte[2048])),但是这句话是什么意思嘛??起什么作用..?
      

  8.   

    是不是使用到的stream没有关闭,猜测~~~~~~
      

  9.   

    逻辑看上去有点乱,看不出来在哪里错了。。
    在这里调用sleep感觉。。,不知道楼主是怎么想的。
     System.out.println(ii);
     Thread.sleep(1000);
      

  10.   


    看看这个,对你网络通信项目有帮助
    http://blog.csdn.net/hzhxxx/archive/2009/12/22/5054785.aspx
      

  11.   


    我也遇到了类似的问题,在使用dos.readInt时 客户端的监听线程抛出异常java.net.SocketException: socket closed,我试了一下如果只是调用run并没有问题,只是用start启动线程就会出现问题,非常郁闷,不知道你的问题现在解决的没有?