我研究了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 (虽然我书中的数字表明客户端和服务器的端口号应该不同,但你永远不知道)
此外,我经常收到此错误消息: 已经在使用的地址听起来像客户端和服务器端口号应该是不同的。但我不知道,这就是我要问的原因。谢谢您的帮助 (该页面不喜欢我的代码所以我拍了截图:/)
我用代码替换了图像。抱歉给你带来不便。 首先使用输入2222重新启动服务器,然后使用输入127.0.0.1 2222重新启动客户端。一段时间后,客户端发布&#34; IO-Error&#34;。它是clien类(不是来自协议类)的例外吗?为什么会触发异常?代码是否适用于某人?谢谢
答案 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等。如果不需要本机套接字,例如您与微控制器通信,则应使用这些技术,因为它们更加强大,而其他技术可以轻松地与您的界面进行通信。