socket发送字符流,无法接收回复的流

本文探讨了Socket通信中客户端和服务端出现阻塞的原因,并通过调整流操作顺序及使用PrintWriter正确发送消息来解决问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

0 0

socket发送字符流,无法接收回复的流3

服务端: 
Java代码   收藏代码
  1. package socket;  
  2.   
  3. import java.io.IOException;  
  4. import java.net.ServerSocket;  
  5. import java.net.Socket;  
  6.   
  7. public class SocketServer {  
  8.     ServerSocket serverSocket = null;  
  9.     Socket socket = null;  
  10.       
  11.     public SocketServer() {  
  12.         try {  
  13.             init();  
  14.         } catch (Exception e) {  
  15.             // TODO Auto-generated catch block  
  16.             e.printStackTrace();  
  17.         }  
  18.     }  
  19.       
  20.     public void init() throws Exception {  
  21.         serverSocket = new ServerSocket(9999);  
  22.     }  
  23.       
  24.     public void run() {  
  25.         try {  
  26.             while(true) {  
  27.                 socket = serverSocket.accept();  
  28.                 MyServer ms = new MyServer(socket);  
  29.                 Thread td = new Thread(ms);  
  30.                 td.start();  
  31.             }  
  32.         } catch (IOException e) {  
  33.             // TODO Auto-generated catch block  
  34.             e.printStackTrace();  
  35.         }  
  36.     }  
  37.   
  38.     /** 
  39.      * @param args 
  40.      */  
  41.     public static void main(String[] args) {  
  42.         // TODO Auto-generated method stub  
  43.         SocketServer ss = new SocketServer();  
  44.         ss.run();  
  45.     }  
  46. }  



Java代码   收藏代码
  1. package socket;  
  2.   
  3. import java.io.BufferedReader;  
  4. import java.io.BufferedWriter;  
  5. import java.io.IOException;  
  6. import java.io.InputStream;  
  7. import java.io.InputStreamReader;  
  8. import java.io.OutputStreamWriter;  
  9. import java.io.OutputStream;  
  10. import java.io.PrintWriter;  
  11. import java.net.Socket;  
  12.   
  13. import file.HandleFile;  
  14.   
  15. public class MyServer implements Runnable {  
  16.     Socket socket = null;  
  17.     PrintWriter pw = null;  
  18.       
  19.     public MyServer(Socket socket) {  
  20.         this.socket = socket;  
  21.     }  
  22.   
  23.   
  24.     public void run() {  
  25.         // TODO Auto-generated method stub  
  26.         try {  
  27.             if(socket == null) {  
  28.                 throw new Exception();  
  29.             }  
  30.               
  31.             BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));  
  32.             BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));  
  33.             StringBuffer sb = new StringBuffer();  
  34.             String tmp = null;  
  35.             while((tmp = br.readLine()) != null) {  
  36.                 sb.append(tmp);  
  37.             }  
  38.             System.out.println(sb.toString());  
  39.               
  40.             pw = new PrintWriter(bw);  
  41.             pw.println("袁泉");  
  42.             pw.flush();  
  43.         } catch (Exception e) {  
  44.             // TODO Auto-generated catch block  
  45.             e.printStackTrace();  
  46.         } finally {  
  47.             pw.close();  
  48.         }  
  49.     }  
  50.   
  51. }  



客户端: 
Java代码   收藏代码
  1. package socket;  
  2.   
  3. import java.io.BufferedReader;  
  4. import java.io.BufferedWriter;  
  5. import java.io.FileOutputStream;  
  6. import java.io.IOException;  
  7. import java.io.InputStream;  
  8. import java.io.InputStreamReader;  
  9. import java.io.OutputStream;  
  10. import java.io.OutputStreamWriter;  
  11. import java.io.PrintWriter;  
  12. import java.net.Socket;  
  13.   
  14. import file.HandleFile;  
  15.   
  16. public class SocketClient {  
  17.     Socket socket = null;  
  18.     FileOutputStream fops = null;  
  19.     OutputStream out = null;  
  20.     InputStream input = null;  
  21.     PrintWriter pw = null;  
  22.       
  23.     SocketClient() {  
  24.         try {  
  25.             init();  
  26.         } catch (Exception e) {  
  27.             // TODO Auto-generated catch block  
  28.             e.printStackTrace();  
  29.         }  
  30.     }  
  31.       
  32.     private void init() throws Exception {  
  33.         socket = new Socket("127.0.0.1"9999);  
  34.     }  
  35.       
  36.     public void run() {  
  37.         try {  
  38.             BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));  
  39.             pw = new PrintWriter(bw);  
  40.             pw.println("夏雨");  
  41.             pw.flush();  
  42.   
  43.             BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));  
  44.             StringBuffer sb = new StringBuffer();  
  45.             String temp = null;  
  46.             while((temp = br.readLine()) != null) {  
  47.                 sb.append(temp);  
  48.             }  
  49.             System.out.println(sb.toString());        
  50.         } catch (Exception e) {  
  51.             // TODO Auto-generated catch block  
  52.             e.printStackTrace();  
  53.         } finally {  
  54.             pw.close();  
  55.               
  56.         }  
  57.     }  
  58.       
  59.     public static void main(String[] args) {  
  60.         // TODO Auto-generated method stub  
  61.         SocketClient sc = new SocketClient();  
  62.         sc.run();  
  63.     }  
  64.   
  65. }  


不知道哪里阻塞了,消息也没发送过去 
2010年5月08日 14:56

4个答案按时间排序按投票排序

0 0

注意用PrintWriter,在往流中写时,要记得flush,也可以用new PrintWriter(writer,true)让它自动flush。 

还有,服务器端和客户端的动作要一致,服务器先写,那么客户就先读,先写就是socket.getOutputStream()在socket.getInputStream()之前调用,反之亦然。否则会造成阻塞。 

以下代码供参考: 

Java代码   收藏代码
  1. package org.zergle.test.socket.server;  
  2.   
  3. import java.net.InetAddress;  
  4. import java.net.ServerSocket;  
  5. import java.net.Socket;  
  6. import java.util.Date;  
  7. import java.util.ArrayList;  
  8. import java.util.List;  
  9.   
  10. /** 
  11.  * 服务器 
  12.  *  
  13.  * @author Johnson Lee 
  14.  *  
  15.  */  
  16. public class Server {  
  17.     private boolean running;  
  18.     private List<ConnectedClient> clients;  
  19.     private ServerSocket svrSocket;  
  20.   
  21.     public Server() {  
  22.         this.running = true;  
  23.         this.clients = new ArrayList<ConnectedClient>();  
  24.     }  
  25.   
  26.     public boolean isRunning() {  
  27.         return running;  
  28.     }  
  29.   
  30.     public void run() {  
  31.         try {  
  32.             this.svrSocket = new ServerSocket(9090);  
  33.             System.err.println("Server started on "  
  34.                     + new java.sql.Date(new Date().getTime()));  
  35.             while (running) {  
  36.                 Socket cltSocket = this.svrSocket.accept();  
  37.                 // 保存客户端的连接  
  38.                 InetAddress ip = cltSocket.getInetAddress();  
  39.                 int port = cltSocket.getPort();  
  40.                 ConnectedClient client = new ConnectedClient(ip, port);  
  41.                 this.clients.add(client);  
  42.                 System.err.println(ip + " connected.");  
  43.                 // 为每个客户端开一个线程  
  44.                 new Thread(new RequestProcessor(this, cltSocket)).start();  
  45.             }  
  46.         } catch (Exception e) {  
  47.             this.running = false;  
  48.         }  
  49.     }  
  50.   
  51.     /** 
  52.      * 连接到服务器端的客户端 
  53.      *  
  54.      * @author Johnson Lee 
  55.      *  
  56.      */  
  57.     private static class ConnectedClient {  
  58.         public InetAddress ip;  
  59.         public int port;  
  60.   
  61.         public ConnectedClient(InetAddress ip, int port) {  
  62.             super();  
  63.             this.ip = ip;  
  64.             this.port = port;  
  65.         }  
  66.   
  67.         @Override  
  68.         public boolean equals(Object obj) {  
  69.             if (obj instanceof ConnectedClient) {  
  70.                 ConnectedClient c = (ConnectedClient) obj;  
  71.                 return c.ip.equals(this.ip) && c.port == this.port;  
  72.             }  
  73.             return false;  
  74.         }  
  75.     }  
  76.   
  77.     /** 
  78.      * @param args 
  79.      */  
  80.     public static void main(String[] args) {  
  81.         new Server().run();  
  82.     }  
  83. }  

Java代码   收藏代码
  1. package org.zergle.test.socket.server;  
  2.   
  3. import java.io.BufferedReader;  
  4. import java.io.IOException;  
  5. import java.io.InputStream;  
  6. import java.io.InputStreamReader;  
  7. import java.io.PrintWriter;  
  8. import java.net.InetAddress;  
  9. import java.net.Socket;  
  10. import java.net.SocketException;  
  11.   
  12. /** 
  13.  * 服务器端用于处理客户连接的处理器 
  14.  *  
  15.  * @author Johnson Lee 
  16.  *  
  17.  */  
  18. public class RequestProcessor implements Runnable {  
  19.     private Server server;  
  20.     private Socket socket;  
  21.   
  22.     public RequestProcessor(Server server, Socket socket) {  
  23.         this.server = server;  
  24.         this.socket = socket;  
  25.     }  
  26.   
  27.     @Override  
  28.     public void run() {  
  29.         if (this.server.isRunning() && this.socket != null  
  30.                 && this.socket.isConnected()) {  
  31.             InetAddress ip = this.socket.getInetAddress();  
  32.             BufferedReader br = null;  
  33.             PrintWriter pw = null;  
  34.             String line = null;  
  35.             try {  
  36.                 InputStream is = this.socket.getInputStream();  
  37.                 br = new BufferedReader(new InputStreamReader(is));  
  38.                 pw = new PrintWriter(this.socket.getOutputStream(), true);  
  39.                 while ((line = br.readLine()) != null) {  
  40.                     System.out.println(line);  
  41.                     pw.println("服务器自动回复 ^_^ ");  
  42.                     pw.flush();  
  43.                 }  
  44.             } catch (SocketException e) {  
  45.                 System.err.println("客户端 " + ip + " 已断开连接");  
  46.             } catch (IOException e) {  
  47.                 e.printStackTrace();  
  48.             } finally {  
  49.                 try {  
  50.                     if (br != null) {  
  51.                         br.close();  
  52.                         br = null;  
  53.                     }  
  54.                 } catch (IOException e) {  
  55.                 }  
  56.             }  
  57.         }  
  58.     }  
  59. }  

Java代码   收藏代码
  1. package org.zergle.test.socket.client;  
  2.   
  3. import java.io.BufferedReader;  
  4. import java.io.IOException;  
  5. import java.io.InputStream;  
  6. import java.io.InputStreamReader;  
  7. import java.io.OutputStream;  
  8. import java.io.PrintWriter;  
  9. import java.net.InetSocketAddress;  
  10. import java.net.Socket;  
  11.   
  12. /** 
  13.  * 客户端 
  14.  *  
  15.  * @author Johnson Lee 
  16.  *  
  17.  */  
  18. public class Client {  
  19.     private InetSocketAddress svrAddress;  
  20.     private Socket svrSocket;  
  21.   
  22.     public Client(String host, int port) {  
  23.         this.svrAddress = new InetSocketAddress(host, port);  
  24.     }  
  25.   
  26.     public void connect() throws IOException {  
  27.         this.svrSocket = new Socket(svrAddress.getAddress(), svrAddress  
  28.                 .getPort());  
  29.     }  
  30.   
  31.     public boolean isClosed() {  
  32.         return this.svrSocket == null || this.svrSocket.isClosed();  
  33.     }  
  34.   
  35.     public InputStream getInputStream() throws IOException {  
  36.         return this.svrSocket.getInputStream();  
  37.     }  
  38.   
  39.     public OutputStream getOutputStream() throws IOException {  
  40.         return this.svrSocket.getOutputStream();  
  41.     }  
  42.   
  43.     /** 
  44.      * @param args 
  45.      */  
  46.     public static void main(String[] args) {  
  47.         BufferedReader br = null;  
  48.         PrintWriter pw = null;  
  49.         String line = null;  
  50.         try {  
  51.             final Client c = new Client("127.0.0.1"9090);  
  52.             c.connect();// 连接服务器  
  53.             try {  
  54.                 br = new BufferedReader(new InputStreamReader(System.in));  
  55.                 pw = new PrintWriter(c.getOutputStream(), true);  
  56.                 new Thread(new ResponseProcessor(c)).start();  
  57.                 while (!c.isClosed()) {  
  58.                     line = br.readLine();  
  59.                     pw.println(line);  
  60.                 }  
  61.             } catch (IOException e) {  
  62.                 e.printStackTrace();  
  63.             } finally {  
  64.                 try {  
  65.                     if (br != null) {  
  66.                         br.close();  
  67.                         br = null;  
  68.                     }  
  69.                     if (pw != null) {  
  70.                         pw.close();  
  71.                         pw = null;  
  72.                     }  
  73.                 } catch (IOException e) {  
  74.                 }  
  75.             }  
  76.         } catch (IOException e) {  
  77.             e.printStackTrace();  
  78.         }  
  79.     }  
  80.   
  81. }  

Java代码   收藏代码
  1. package org.zergle.test.socket.client;  
  2.   
  3. import java.io.BufferedReader;  
  4. import java.io.IOException;  
  5. import java.io.InputStreamReader;  
  6. import java.io.PrintWriter;  
  7. import java.net.SocketException;  
  8.   
  9. /** 
  10.  * 服务端响应处理器 
  11.  *  
  12.  * @author Johnson Lee 
  13.  *  
  14.  */  
  15. public class ResponseProcessor implements Runnable {  
  16.     private Client client;  
  17.   
  18.     public ResponseProcessor(Client c) {  
  19.         super();  
  20.         this.client = c;  
  21.     }  
  22.   
  23.     @Override  
  24.     public void run() {  
  25.         BufferedReader br = null;  
  26.         PrintWriter pw = null;  
  27.         String line = null;  
  28.         try {  
  29.             br = new BufferedReader(new InputStreamReader(client  
  30.                     .getInputStream()));  
  31.             pw = new PrintWriter(System.out, true);  
  32.             while (!client.isClosed()) {  
  33.                 line = br.readLine();  
  34.                 pw.println(line);  
  35.             }  
  36.         } catch (SocketException e) {  
  37.             if (!client.isClosed()) {  
  38.                 System.err.println(e);  
  39.             }  
  40.         } catch (IOException e) {  
  41.             e.printStackTrace();  
  42.         }  
  43.     }  
  44.   
  45. }  

2010年5月10日 15:16
0 0

Java代码   收藏代码
  1. while((tmp = br.readLine()) != null) {    
  2.                 sb.append(tmp);    
  3.             }   

这行阻塞了,客户端的writer只是flush没有关闭,这个方法会一直等待知道客户输出流关闭。 
MyServer类改成: 
Java代码   收藏代码
  1. ...  
  2. while ((tmp = br.readLine()) != null) {  
  3.                 System.out.println(tmp);  
  4.                 sb.append(tmp);  
  5.                 pw = new PrintWriter(bw,true);  
  6.                 pw.println("袁泉");  
  7.             }  

SockerClient改成: 
Java代码   收藏代码
  1. BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));  
  2.             BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));  
  3.   
  4.             pw = new PrintWriter(bw, true);  
  5.             pw.println("夏雨");  
  6.   
  7.             BufferedInputStream bin = new BufferedInputStream(System.in);  
  8.             sc = new Scanner(bin);  
  9.   
  10.             StringBuffer sb = new StringBuffer();  
  11.             String temp = null;  
  12.             while ((temp = br.readLine()) != null) {  
  13.                 System.out.println(temp);  
  14.                 String line = sc.nextLine();  
  15.                 pw.println(line);  
  16.             }  

即可实现互发消息

2010年5月09日 00:46
0 0

你的server和client都用了PrintWriter的readLine()方法,这个方法阻塞了,因为你两边发送的都是几个字符,其中没有换行 ('\n')或者回车 ('\r'),因此,两边的这个方法就一直阻塞着。

2010年5月08日 23:59
0 0

PrintWriter 的 println 是打印字符串。在socket编程中使用的是write。。 

============= 
注意了write使用,字符串必须加上换行(“\n”)

2010年5月08日 23:46
    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值