网络编程中(单主机)聊天程序的实现中实现非一问一答式的方法解答
注:以下代码时在单一主机上执行的,该电脑既是客户端又是服务端
服务端的问题
在学习网络编程时我发现一些问题:在使用TCP亦或者UDP的时候,两者在编写聊天平台时都存在一个问题,首先是服务端,
问题一:一次只可以接收一句话,如果一句话在客户端分两次发出,则服务端首先只能收到第一句话,第二句话在自身发出消息后才能收到
问题二:在服务端首先发出消息后,它并非按照规定的编写顺序执行代码,如以下代码:
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class ChatServer {
public static void main(String[] args) {
System.out.println("Server Online!");
Thread thr = new Thread(()->{
try ( ServerSocket sersoc = new ServerSocket(1777);
Socket soc = sersoc.accept();
DataInputStream datain = new DataInputStream(soc.getInputStream());
DataOutputStream dataout = new DataOutputStream(soc.getOutputStream());
BufferedReader keyIn = new BufferedReader(new InputStreamReader(System.in))){
while(true){
String str = datain.readUTF();
labelone:while(str!=null){
System.out.printf("Received Message:[%s]\n",str);
break;
}
String keyboardInput = keyIn.readLine();
if(keyboardInput.equals("bye")){
break;
}
/*>>>问题代码<<<*/ System.out.println("Sent:"+keyboardInput);
dataout.writeUTF(keyboardInput);
dataout.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("System offline!");
});
thr.start();
}
}
在上述代码中,如果服务器端首先发送信息成立,则说明问题代码的下一行代码执行成功,则程序已成功跳出该段代码以上的代码。但输出结果充,则为图一:
问题代码并未执行,此时服务端实际上已经收到了消息(但是目前存在尚未解决,问题在稍后提出,总之此时如果客户端发出消息会收到服务端的信息,见图二),而此时当服务端收到消息后会显示图三
图二:
图三:
——————————————-分割线——————————————————–
客户端的问题
然后是客户端:
问题一:客户端的首先必须将发送语句写在最前面,否则,将无法正常输出,导致服务端甚至无法收取信息,客户端代码如下:
import java.io.*;
import java.net.ConnectException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
public class ChatClient {
public static void main(String[] args) {
System.out.println("Client Online!");
Thread t= new Thread(()->{
try( Socket soc = new Socket(InetAddress.getLocalHost(),1777);
DataInputStream in = new DataInputStream(soc.getInputStream());
DataOutputStream out = new DataOutputStream(soc.getOutputStream());
BufferedReader keyIn = new BufferedReader(new InputStreamReader(System.in))) {
while(true){
String str = in.readUTF();
if(str!=""){
System.out.printf("Received Message:[%s]\n",str);
break;
}else {
String keboardInput = keyIn.readLine();
if (keboardInput.equals("bye")) {
break;
}
out.writeUTF(keboardInput);
out.flush();
}
}
} catch (ConnectException e) {
System.out.println("Cant connect to the server!");
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("Server offline!");
});
t.start();
}
}
以上代码因为将发送代码写在前面,所以尝试使用了循环语句,因为本人在API文档中找不到符合的方法实现:如果接口接收到消息则显示TRUE的方法,因此尝试使用读取字符串是否为空的条件,但是做造成的结果是客户端无法发送,服务端无法接收,以下是修改后的服务端代码:
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class ChatServer {
public static void main(String[] args) {
System.out.println("Server Online!");
Thread thr = new Thread(()->{
try ( ServerSocket sersoc = new ServerSocket(1777);
Socket soc = sersoc.accept();
DataInputStream datain = new DataInputStream(soc.getInputStream());
DataOutputStream dataout = new DataOutputStream(soc.getOutputStream());
BufferedReader keyIn = new BufferedReader(new InputStreamReader(System.in))){
while(true){
String str = datain.readUTF();
if(str!=""){
System.out.printf("Received Message:[%s]\n",str);
break;
}else {
String keyboardInput = keyIn.readLine();
if (keyboardInput.equals("bye")) {
break;
}
System.out.println("Sent:" + keyboardInput);
dataout.writeUTF(keyboardInput);
dataout.flush();
}
}
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("System offline!");
});
thr.start();
}
}
此时两端均无法正常工作
其次是:
问题二:客户端必须是在发送后才可以执行接收得代码