简体   繁体   English

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

[英]Client-Server example does not work

I studied the Client-Server chapter of a Java book and I copied the code examples for a easy Client-Server interaction. 我研究了一本Java书籍的“客户端-服务器”一章,并复制了代码示例以简化客户端-服务器的交互。

The 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();
    }

}

}

Protocol: 协议:

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");
}
}

The Client: 客户端:

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");
    }



}

}

Here are some notes of my approach and my beliefs. 以下是关于我的方法和信念的一些说明。 Please disagree on wrong statements stated below: 请不同意以下错误陈述:

1)I believe it is no problem to run Client as well as Server on the same (my) computer. 1)我相信在同一台(我的)计算机上运行客户端和服务器没有问题。

2)I use Eclipse, so I run Eclipse two times in two different workspaces. 2)我使用Eclipse,所以我在两个不同的工作区中两次运行Eclipse。

3)My input for server program is (run configuration->arguments): 2222 3)我对服务器程序的输入是(运行配置->参数):2222

4)My input for the client program is: 2223 my_ip (my_ip is for example 127.0.0.1 I choosed to write my_ip instead because I am not sure if it is dangerous to reaveal my ip in public) 4)我对客户端程序的输入是:2223 my_ip(例如,my_ip例如127.0.0.1,我选择写my_ip来代替,因为我不确定在公共场合撤回我的IP是否有危险)

4b) also: "2223" "my_ip" 4b)也:“ 2223”“ my_ip”

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

5) also 2222 my_ip (although the figure in my book suggests that the port numbers of client and server should be different, but you never know) 5)也为2222 my_ip(尽管我的书中的数字表明客户端和服务器的端口号应该不同,但您永远不知道)

Also I get this very often this error message: 我也经常收到此错误消息: 在此处输入图片说明 Address already in use sounds like client and server port numbers should be different. 客户端和服务器端口号之类的已经使用的地址听起来应该不同。 But I dont know and thats why I ask. 但是我不知道,这就是为什么我问。 Thank you for your help (The page did not like my code so I took screenshots :/) 谢谢您的帮助(该页面不喜欢我的代码,因此我截取了屏幕截图:/)

I replaced the images with code. 我用代码替换了图像。 Sorry for the inconvenience. 抱歉给你带来不便。 Restarting first the server with input 2222 and then the client with input 127.0.0.1 2222. After a while the client posts "IO-Error". 首先使用输入2222重新启动服务器,然后使用输入127.0.0.1 2222重新启动客户端。过一会儿,客户端发布“ IO错误”。 Its the exception from the clien class (not from protocol class) right? 它是来自clien类(不是来自协议类)的例外,对吗? Why is the exception triggered? 为什么触发异常? Is the code working for someone? 该代码对某人有用吗? Thank you 谢谢

1) Correct. 1)正确。 Client and server can be on the same computer, no problem there. 客户端和服务器可以在同一台计算机上,在那里没有问题。

2) Not required, but ok. 2)不需要,但是还可以。

3) This will make the server listen on port 2222 3)这将使服务器在端口2222上进行侦听

4) 127.0.0.1 is just another way of saying "this computer". 4)127.0.0.1只是说“这台计算机”的另一种方式。 It is the same as "localhost". 它与“ localhost”相同。 Your actual ip is irrelevant to the question anyway, 127.0.0.1 will suffice. 无论如何,您的实际IP与问题无关,127.0.0.1就足够了。

5) Your server is asking on which port to listen (the SOURCE port), your client is asking to which port to connect to (the TARGET port of the client). 5)您的服务器正在询问要侦听的端口(SOURCE端口),客户端正在询问要连接到的端口(客户端的TARGET端口)。 Of course that should be the SAME port, otherwise the client will try to send a message to port X while the server will listen on port Y. 当然这应该是SAME端口,否则客户端将尝试向端口X发送消息,而服务器将在端口Y上侦听。

Imagine the ip as a house address, for example "Mainstreet 12, MyCity". 将该ip想象成一个家庭地址,例如“ Mainstreet 12,MyCity”。 The port would be the appartment number then. 然后,端口将是公寓号。 Your server occupies appartment 2222, so of course the client needs to try to connect to appartment 2222, otherwise it will not reach any server. 您的服务器占用了2222单元,因此客户端当然需要尝试连接到2222单元,否则它将无法访问任何服务器。

The error is most likely just because you don't actually stop your old server program. 该错误很可能是因为您实际上并未停止旧服务器程序。 Stop it (big red button in eclipse), otherwise it will "occupy" the given port (which will prevent any other program from listing at that port, thus you cannot have two servers running which are both listening on the same port). 停止它(eclipse中的红色大按钮),否则它将“占用”给定的端口(这将阻止任何其他程序在该端口上列出,因此您不能同时运行两个正在侦听同一端口的服务器)。 If we reuse my crude analogy: An appartment cannot contain two servers at the same time, so if one is already in appartment 2222, a second one trying to live there will fail. 如果我们重复使用粗略的类比:一个公寓不能同时包含两个服务器,因此如果一个已经在公寓2222中,则第二个尝试在其中居住的服务器将失败。

I don't know exactly why, but usually server binds host as 127.0.0.1 or localhost or your IP like 192.168.1.100 but if one of that are not listed, than it might be failed to call. 我不知道为什么,但是通常服务器将主机绑定为127.0.0.1或localhost或您的IP像192.168.1.100,但是如果未列出其中之一,则可能无法调用。 See more with netstat.exe on Windows. 在Windows上使用netstat.exe查看更多信息。

The "Address already in use" exception is only because the last Java session still running, could not terminate for some reason, and if you use IDE like Eclipse, it will often happen. “地址已在使用中”异常仅是因为最后一个Java会话仍在运行,由于某种原因而无法终止,并且,如果您使用像Eclipse这样的IDE,它经常会发生。 :) Make sure that all java thread is terminated (with task manager in Windows). :)确保终止所有Java线程(在Windows中使用任务管理器)。 Note that Eclipse is a Java thread too! 注意,Eclipse也是Java线程! You would better run the server in console mode.. 您最好在控制台模式下运行服务器。

In real world, native sockets are rarely used, because there some higher level protocol and technology like HTTP, SOAP, WebService, microService, SOA etc. If native socket is not necessary, for example you communicate with microcontroller, you should use these technologies, because these are more robust and others can easily communicate with your interface. 在现实世界中,很少使用本机套接字,因为存在一些更高级别的协议和技术,例如HTTP,SOAP,WebService,microService,SOA等。如果不需要本机套接字,例如与微控制器通信,则应使用这些技术,因为这些功能更强大,其他功能则可以轻松与您的界面进行通信。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM