我研究了Java书籍的“客户端-服务器”一章,并复制了代码示例,以实现轻松的客户端-服务器交互。

服务器:

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)我相信在同一台(我的)计算机上运行客户端和服务器没有问题。

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

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

4)我对客户端程序的输入是:2223 my_ip
 (例如,my_ip是127.0.0.1,我选择写my_ip来代替,因为我不确定在公共场合撤回我的IP是否有危险)

4b)也:“ 2223”“ my_ip”

4c)和:{“ 2223”,“ my_ip”}

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

我也经常收到此错误消息:

客户端和服务器端口号之类的已经使用的地址听起来应该不同。但是我不知道,这就是为什么我问。谢谢您的帮助
(该页面不喜欢我的代码,所以我截取了屏幕截图:/)

我用代码替换了图像。抱歉给你带来不便。
首先使用输入2222重新启动服务器,然后使用输入127.0.0.1 2222重新启动客户端。过一会儿,客户端发布“ IO错误”。它是来自clien类(不是来自协议类)的例外,对吗?为什么触发异常?该代码对某人有用吗?谢谢

最佳答案

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

2)不需要,但是还可以。

3)这将使服务器在端口2222上进行侦听

4)127.0.0.1只是说“这台计算机”的另一种方式。它与“ localhost”相同。无论如何,您的实际IP与问题无关,127.0.0.1就足够了。

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

将该ip想象成一个家庭地址,例如“ Mainstreet 12,MyCity”。端口将是公寓编号。您的服务器占用了2222单元,因此客户端当然需要尝试连接到2222单元,否则它将无法访问任何服务器。

该错误很可能只是因为您实际上并未停止旧服务器程序。停止它(eclipse中的红色大按钮),否则它将“占用”给定的端口(这将阻止任何其他程序在该端口上列出,因此您不能同时运行两个正在侦听同一端口的服务器)。如果我们重复使用粗略的类比:一个公寓不能同时包含两台服务器,因此,如果其中一个已经在公寓2222中,则第二个尝试在其中居住的服务器将失败。

08-05 06:18
查看更多