客户端 - 服务器示例不起作用

时间:2015-03-17 20:15:43

标签: java eclipse

我研究了Java书籍的Client-Server章节,并复制了代码示例,以便进行简单的客户端 - 服务器交互。

服务器:

package knowledge;

import java.io.*;
import java.net.*;

public class DateTimeServer {

public static void main(String[] args) {
    try {
        int port = Integer.parseInt(args[0]);
        ServerSocket server = new ServerSocket(port);
        System.out.println("DateTimeServer laeuft");
        Socket s = server.accept();
        new DateTimeProtokoll(s).transact();
    } catch (ArrayIndexOutOfBoundsException ae) {
        System.out.println("Aufruf: java DateTimeServer <Port-Nr>");
    } catch (IOException e) {
        e.printStackTrace();
    }

}

}

协议:

package knowledge;

import java.io.*;
import java.net.*;
import java.util.*;
import java.text.*;

public class DateTimeProtokoll {
static SimpleDateFormat time = new SimpleDateFormat(
        "´Es ist gerade´H´.´mm´ Uhr.´");
static SimpleDateFormat date = new SimpleDateFormat(
        "´Heute ist´EEEE´, der ´dd.MM.yy´");

Socket s;
BufferedReader vomClient;
PrintWriter zumClient;

public DateTimeProtokoll(Socket s) {
    try {
        this.s = s;
        vomClient = new BufferedReader(new InputStreamReader(
                s.getInputStream()));
        zumClient = new PrintWriter(s.getOutputStream(), true);
    } catch (IOException e) {
        System.out.println("IO-Error");
        e.printStackTrace();
    }
}

public void transact() {
    System.out.println("Protokoll gestartet");
    try {
        zumClient.println("Geben Sie DATE oder TIME ein");
        String wunsch = vomClient.readLine();
        Date jetzt = new Date();

        if (wunsch.equalsIgnoreCase("date"))
            zumClient.print(date.format(jetzt));
        else if (wunsch.equalsIgnoreCase("time"))
            zumClient.println(time.format(jetzt));
        else
            zumClient.println(wunsch + "ist als Kommando unzulaessig!");
        s.close();
    } catch (IOException e) {
        System.out.println("IO-Error");
    }

    System.out.println("Protokoll beendet");
}
}

客户:

package knowledge;
import java.net.*;
import java.io.*;


public class DateTimeClient {

public static void main(String[] args) {
    String hostName="";
    int port;
    Socket c=null;

    try{
        hostName=args[0];
        port= Integer.parseInt(args[1]);
        c=new Socket(hostName,port);

        BufferedReader vomServer=new BufferedReader(
                                        new InputStreamReader(c.getInputStream()));

        PrintWriter zumServer=new PrintWriter(c.getOutputStream(),true);

        BufferedReader vonTastatur=new BufferedReader(
                                        new InputStreamReader(System.in));
        System.out.println("Server "+ hostName+":"+port+ "sagt:");
        String text=vomServer.readLine();
        System.out.println(text);
        text=vonTastatur.readLine();
        zumServer.println(text);
        text=vomServer.readLine();
        System.out.println(text);

        c.close();
    }
    catch(ArrayIndexOutOfBoundsException ae){
        System.out.println("Aufruf:");
        System.out.println("java DateTimeClient <HostName><PortNr>");
    }
    catch(UnknownHostException ue){
        System.out.println("Kein DNS-Eintrag fuer: "+hostName);
    }
    catch(IOException e){
        System.out.println("IO-Error");
    }



}

}

以下是我的方法和我的信念的一些注释。请不要同意以下错误陈述:

1)我认为在同一台(我的)计算机上运行Client和Server是没有问题的。

2)我使用Eclipse,因此我在两个不同的工作区中运行Eclipse两次。

3)我对服务器程序的输入是(运行配置 - >参数):2222

4)我对客户端程序的输入是:2223 my_ip  (my_ip是例如127.0.0.1我选择写my_ip而不是因为我不确定在公共场合重新打开我的ip是否有危险)

4b)同时:&#34; 2223&#34; &#34; my_ip&#34;

4c)和:{&#34; 2223&#34;,&#34; my_ip&#34;}

5)也是2222 my_ip  (虽然我书中的数字表明客户端和服务器的端口号应该不同,但你永远不知道)

此外,我经常收到此错误消息: enter image description here 已经在使用的地址听起来像客户端和服务器端口号应该是不同的。但我不知道,这就是我要问的原因。谢谢您的帮助 (该页面不喜欢我的代码所以我拍了截图:/)

我用代码替换了图像。抱歉给你带来不便。 首先使用输入2222重新启动服务器,然后使用输入127.0.0.1 2222重新启动客户端。一段时间后,客户端发布&#34; IO-Error&#34;。它是clien类(不是来自协议类)的例外吗?为什么会触发异常?代码是否适用于某人?谢谢

2 个答案:

答案 0 :(得分:3)

1)正确。客户端和服务器可以在同一台计算机上,没问题。

2)不需要,但确定。

3)这将使服务器侦听端口2222

4)127.0.0.1只是另一种说法&#34;这台电脑&#34;。它与&#34; localhost&#34;相同。无论如何,你的实际ip与问题无关,127.0.0.1就足够了。

5)您的服务器询问要侦听的端口(SOURCE端口),您的客户端询问要连接到哪个端口(客户端的TARGET端口)。当然应该是SAME端口,否则客户端将尝试向端口X发送消息,而服务器将在端口Y上侦听。

想象一下ip作为住宅地址,例如&#34; Mainstreet 12,MyCity&#34;。那么端口就是公寓号码。您的服务器占用了公寓2222,因此客户端当然需要尝试连接到公寓2222,否则它将无法访问任何服务器。

错误很可能只是因为您实际上没有停止旧的服务器程序。停止它(日食中的大红色按钮),否则它将占据&#34;给定的端口(这将阻止任何其他程序在该端口列出,因此您不能运行两个服务器,它们都在同一端口上侦听)。如果我们重复使用我粗略的类比:一个公寓不能同时包含两个服务器,所以如果一个已经在公寓2222,第二个试图住在那里将失败。

答案 1 :(得分:0)

我不确切知道原因,但通常服务器将主机绑定为127.0.0.1或localhost,或者将IP绑定为192.168.1.100,但如果其中一个未列出,则可能无法调用。有关Windows上的netstat.exe的更多信息,请参阅。

&#34;地址已在使用&#34;异常仅仅是因为最后一个Java会话仍在运行,由于某些原因无法终止,如果你像Eclipse一样使用IDE,它会经常发生。 :) 确保所有java线程都已终止(使用Windows中的任务管理器)。请注意,Eclipse也是一个Java线程!您最好在控制台模式下运行服务器..

在现实世界中,很少使用本机套接字,因为有一些更高级别的协议和技术,如HTTP,SOAP,WebService,microService,SOA等。如果不需要本机套接字,例如您与微控制器通信,则应使用这些技术,因为它们更加强大,而其他技术可以轻松地与您的界面进行通信。