关于socket 实现聊天室时客户端导致readline出现阻塞解决办法

客户端:

	  String val=req.getParameter("text").toString();
		  String id=req.getParameter("id");
		  Socket socket =null; 
		  if(id==null||id.equals("")){
			  socket= new Socket("127.0.0.1",8090);
			  id=socketFactory.getNewId()+"";
			  socketFactory.add(Integer.parseInt(id), socket);
		  }else{
			  socket=socketFactory.get(Integer.parseInt(id));
			
		  }
		  OutputStream os=socket.getOutputStream();
		  //向页面传递
		  PrintWriter write=new PrintWriter(resp.getOutputStream());
		  write.write(id);

		  //向服务端传递
		  PrintWriter swrite=new PrintWriter(os);
		  swrite.println("i am client"+id+":"+val);
 	   	  write.close();
// 		 swrite.close();
// 	     	os.close();
//		  os.flush();
		  swrite.flush();
//		  write.flush();


 

服务端:

		 ServerSocket serversocket=new ServerSocket(8090);
		 for(int i=0;i<10;i++){
		 Socket socket=serversocket.accept();
		 System.out.println("获取到请求"); 
		 BufferedReader bread=new BufferedReader(new InputStreamReader(socket.getInputStream()));
		 StringBuilder msg=new StringBuilder();
		 String str=null;
		 while((str=bread.readLine())!=null&&str.length()>0){
			msg.append(str);
		 }
		 
     
		  System.out.print(msg);
		  PrintWriter write= new PrintWriter(socket.getOutputStream());
		  write.write("您好 我是服务端");  //服务端回应
		  write.flush();
		 }

因为想实现在保持socket连接状态下,实现服务端和客户端的互相通信,结果发现,当服务端接收到socket读取数据时,在readline处发现了阻塞的情况,通过查询资料后发现,readline在接收结束信号后才会停止读取数据,这就意味着需要客户端调用close()或者shutdownOutput()时才能够时当前readline()停止。解决办法

1、每次接收只调用一次readline(不加while循环)

2、使用read()方法,加大buff的内存一次性将数据读取出来

3、为一个socket建立线程,服务端修改后代码如下

 

 ServerSocket serversocket=new ServerSocket(8090);
   ExecutorService exec=Executors.newCachedThreadPool();
   for(int i=0;i<10;i++){
   Socket socket=serversocket.accept();
   exec.execute(new Runnable() {  //启用线程
   
   @Override
   public void run() {
    // TODO Auto-generated method stub

     System.out.println("获取到请求"); 
     BufferedReader bread;
    try {
     bread = new BufferedReader(new InputStreamReader(socket.getInputStream()));
      
      String str=null;
      while((str=bread.readLine())!=null){
       
        System.out.println(str);
      }
    } catch (IOException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }
   }
  });
    PrintWriter write= new PrintWriter(socket.getOutputStream());
    write.write("您好 我是服务端");  //服务端回应
    write.flush();
   }


 

 


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现多个客户的相互聊天功能,可以采用C#中的Socket编程来实现,以下是一个简单的示例代码: 服务代码: ```csharp using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net; using System.Net.Sockets; using System.Threading; namespace Server { class Program { private static Socket serverSocket; private static byte[] buffer = new byte[1024]; private static List<Socket> clientSockets = new List<Socket>(); static void Main(string[] args) { Console.WriteLine("Starting server..."); serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); serverSocket.Bind(new IPEndPoint(IPAddress.Any, 8080)); serverSocket.Listen(5); Console.WriteLine("Server started on port 8080"); while (true) { Socket clientSocket = serverSocket.Accept(); clientSockets.Add(clientSocket); Console.WriteLine($"Client connected: {clientSocket.RemoteEndPoint}"); Thread thread = new Thread(() => ListenClient(clientSocket)); thread.Start(); } } private static void ListenClient(Socket clientSocket) { while (true) { int bytesReceived = clientSocket.Receive(buffer); if (bytesReceived == 0) { clientSockets.Remove(clientSocket); Console.WriteLine($"Client disconnected: {clientSocket.RemoteEndPoint}"); break; } string message = Encoding.ASCII.GetString(buffer, 0, bytesReceived); Console.WriteLine($"Received message '{message}' from client {clientSocket.RemoteEndPoint}"); foreach (Socket socket in clientSockets) { if (socket != clientSocket) { socket.Send(Encoding.ASCII.GetBytes(message)); } } } } } } ``` 客户代码: ```csharp using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net; using System.Net.Sockets; namespace Client { class Program { private static Socket clientSocket; private static byte[] buffer = new byte[1024]; static void Main(string[] args) { Console.WriteLine("Connecting to server..."); clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); clientSocket.Connect(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8080)); Console.WriteLine("Connected to server"); while (true) { Console.Write("Enter message: "); string message = Console.ReadLine(); clientSocket.Send(Encoding.ASCII.GetBytes(message)); int bytesReceived = clientSocket.Receive(buffer); string receivedMessage = Encoding.ASCII.GetString(buffer, 0, bytesReceived); Console.WriteLine($"Received message from server: {receivedMessage}"); } } } } ``` 这里是一个简单的示例,客户和服务都是单线程运行的,无法处理并发连接,需要根据实际需求进行改进。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值