1. 程式人生 > >socket網路程式設計中伺服器與客戶端通訊失敗的問題

socket網路程式設計中伺服器與客戶端通訊失敗的問題

伺服器程式碼如下

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()是一行一行讀取資料,而標識一行的方式就是使用分隔符。