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