繁体   English   中英

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

[英]Client-Server example does not work

我研究了一本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中,则第二个尝试在其中居住的服务器将失败。

我不知道为什么,但是通常服务器将主机绑定为127.0.0.1或localhost或您的IP像192.168.1.100,但是如果未列出其中之一,则可能无法调用。 在Windows上使用netstat.exe查看更多信息。

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

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

暂无
暂无

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

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