socket網路程式設計中伺服器與客戶端通訊失敗的問題
阿新 • • 發佈:2019-01-22
伺服器程式碼如下
public class server {
public static void main(String[] args) throws IOException {
ServerSocket server=new ServerSocket(5678);
Socket socket=server.accept();
InputStream is=socket.getInputStream();
OutputStream os=socket.getOutputStream();
Scanner input=new Scanner(is);
PrintWriter out=new PrintWriter(os,true);
out.print("連結伺服器成功");
out.print("end");
String sr;
while (true) {
sr=input.nextLine();
if (sr.equals("end")) {
break;
}
System.out.println(" 客戶端說" +sr);
}
socket.close();
}
}
客戶端程式碼如下
public class Clint {
public static void main(String[] args) throws UnknownHostException, IOException {
// TODO 自動生成的方法存根
Socket socket=new Socket(InetAddress.getLocalHost(), 5678);
InputStream is=socket.getInputStream();
OutputStream os=socket.getOutputStream();
Scanner in =new Scanner(is);
PrintWriter out=new PrintWriter(os,true);
String sr,sw;
while (true) {
sr=in.nextLine();
System.out.println("伺服器說 "+sr);
if (sr.equals("end")) {
break;
}
}
Scanner input=new Scanner(System.in);
while (true) {
System.out.print(" 客戶端說");
sw=input.next();
out.println(sw);
if (sw.equals("end")) {
break;
}
}
socket.close();
}
}
最初客戶端一直無法讀取到伺服器返回的訊息,後來發現是在伺服器如下兩行程式碼的問題
out.print("連結伺服器成功");
out.print("end");
應該修改為如下程式碼
out.println("連結伺服器成功");
out.println("end");
print的原始碼如下
public void print(String s) {
if (s == null) {
s = "null";
}
write(s);
}
而println的原始碼如下
public void println(String x) {
synchronized (lock) {
print(x);
println();
}
}
而在println(String x)中又呼叫了println()方法
public void println() {
newLine();
}
其中呼叫了newLine()方法
原始碼如下
private void newLine() {
try {
synchronized (lock) {
ensureOpen();
out.write(lineSeparator);
if (autoFlush)
out.flush();
}
}
catch (InterruptedIOException x) {
Thread.currentThread().interrupt();
}
catch (IOException x) {
trouble = true;
}
}
可以看出println()方法中多了一個out.write(lineSeparator);
添加了一個分隔符,並且可以設定自動flush
因為預設的autoFlush=false,可以在建立PrintWriter時設定為true。
PrintWriter writer = new PrintWriter(socket.getOutputStream(),true);
有如下程式碼
inReader.readLine()
可看出readLine()是一行一行讀取資料,而標識一行的方式就是使用分隔符。