《Head First Java》第15章介绍Socket通信时的一个示例程序DailyAdvice,包括客户端DailyAdviceClient,服务器DailyAdviceServer。编译通过,开两个命令行窗口,先运行DailyAdviceServer等待客户端的Socket请求,然后在另一个命令行窗口运行客户端DailyAdviceClient,报错:D:\Code\Head First Java\chap15\DailyAdvice>java DailyAdviceClient
java.net.SocketException: Connection reset
        at java.net.SocketInputStream.read(SocketInputStream.java:168)
        at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264)
        at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)
        at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158)
        at java.io.InputStreamReader.read(InputStreamReader.java:167)
        at java.io.BufferedReader.fill(BufferedReader.java:136)
        at java.io.BufferedReader.readLine(BufferedReader.java:299)
        at java.io.BufferedReader.readLine(BufferedReader.java:362)
        at DailyAdviceClient.go(DailyAdviceClient.java:15)
        at DailyAdviceClient.main(DailyAdviceClient.java:7)同时,服务器端报错:
D:\Code\Head First Java\chap15\DailyAdvice>java DailyAdviceServer
java.net.SocketException: select failed
        at java.net.PlainSocketImpl.socketAccept(Native Method)
        at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:390)
        at java.net.ServerSocket.implAccept(ServerSocket.java:453)
        at java.net.ServerSocket.accept(ServerSocket.java:421)
        at DailyAdviceServer.go(DailyAdviceServer.java:11)
        at DailyAdviceServer.main(DailyAdviceServer.java:30)奇怪的是,程序不做任何修改,在别人的机子上编译运行均正常。本机环境:Win7 64位,java version 1.6.0_21,防火墙已关闭程序源码如下:Server: DailyAdviceServer.javaimport java.io.*;
import java.net.*;public class DailyAdviceServer {
String[] adviceList = {"Take smaller bites", "Go for the tight jeans. No they do NOT make you look fat.", "One word: inappropriate", "Just for today, be honest. Tell your boss what you *really* think", "you might want to rethink that haircut."};

public void go() {
try {
ServerSocket serverSock = new ServerSocket(4242);
while (true) {
Socket sock = serverSock.accept();
PrintWriter writer = new PrintWriter(sock.getOutputStream());
String advice = getAdvice();
writer.println(advice);
writer.close();
System.out.println(advice);
}
} catch (IOException ex) {
ex.printStackTrace();
}
}

private String getAdvice() {
int random = (int) (Math.random() * adviceList.length);
return adviceList[random];
}

public static void main(String[] args) {
DailyAdviceServer server = new DailyAdviceServer();
server.go();
}
}
Client: DailyAdviceClient.javaimport java.io.*;
import java.net.*;public class DailyAdviceClient {
public static void main(String[] args) {
DailyAdviceClient client = new DailyAdviceClient();
client.go();
}

public void go() {
try {
Socket s = new Socket("127.0.0.1", 4242);
InputStreamReader streamReader = new InputStreamReader(s.getInputStream());
BufferedReader reader = new BufferedReader(streamReader);
String advice = reader.readLine();
System.out.println("Today you should: " + advice);
reader.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}

解决方案 »

  1.   

    个人认为:你的 win7使用的是ip6。
    两种方法解决:
    1.将你的机器上ip6改成ip4。
    2.连接时使用ip6的地址的表现方式:例如:127.0.0.1在ip6应该表示为0
      

  2.   


    本地连接的属性中已经去掉了IPV6的勾选,还是不行。同学的机子也是Win7(32位),支持IPV6,ping localhost的地址是::1,但是就没问题。 我的是64位Win7装的32位JDK,会不会是因为64位操作系统的问题?
      

  3.   


    换了个端口 6666, 还是不行。 运行服务器端程序DailyAdviceServer后,在另一个命令行窗口运行netstat -an 可以看到端口6666处于监听状态:
     TCP    0.0.0.0:6666           0.0.0.0:0              LISTENING
     TCP    [::]:6666              [::]:0                 LISTENING3楼的说卸载是指把IPV6卸载了吗?
      

  4.   

    不行就用这个:连接时使用ip6的地址的表现方式:例如:127.0.0.1在ip6应该表示为0。
    Socket s = new Socket("127.0.0.1", 4242);改为:Socket s = new Socket("0", 4242);
      

  5.   


    按照网上的方法改注册表禁用了IPV6协议,运行命令 ipconfig /all只能看到 本地连接, IPV6的隧道适配器都没了。 可是还是不行。7楼的方法还没试过。只有把IPV6重新启用再试一下。
      

  6.   

    -Djava.net.preferIPv4Stack=true
    启动的时候加个参数试试。
      

  7.   

    真神奇,估计是你机器装什么东西装的,tcp协议有点不正常了。
      

  8.   

    估计默认情况下,即使是IPV4和IPV6双栈,java.net.preferIPv4Stack这个JVM系统参数也是默认为true的,可是我的系统不知道怎么回事,在服务器端默认是用的IPV6的Socket格式。问题终于解决了,只要在运行服务器端程序DailyAdviceServer时,指定一个JVM系统属性java.net.preferIPv4Stack的值为true,就可以强制采用IPv4格式的Socket。:\...\>java -Djava.net.preferIPv4Stack=true DailyAdviceServer:\...\>DailyAdvice>java DailyAdviceClient