使用socket开发多线程聊天

如果使用单线程开发Socket应用,那么同一时间,要么收消息,要么发消息,不能同时进行。 

为了实现同时收发消息,就需要用到多线程

  • 同时收发消息

    在服务端和客户端互聊 中,只能一人说一句,说了之后,必须等待另一个人的回复,才能说下一句。

    这是因为接受和发送都在主线程中,不能同时进行。 为了实现同时收发消息,基本设计思路是把收发分别放在不同的线程中进行

    1. SendThread 发送消息线程
    2. RecieveThread 接受消息线程
    3. Server一旦接受到连接,就启动收发两个线程
    4. Client 一旦建立了连接,就启动收发两个线程

    package socket;
     
    import java.io.DataOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.net.Socket;
    import java.util.Scanner;
     
    public class SendThread extends Thread{
     
        private Socket s;
     
        public SendThread(Socket s){
            this.s = s;
        }
        public void run(){
            try {
                OutputStream os = s.getOutputStream();
                DataOutputStream dos = new DataOutputStream(os);
     
                while(true){
                    Scanner sc = new Scanner(System.in);
                    String str = sc.next();
                    dos.writeUTF(str);
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
             
        }
         
    }
    package socket;
     
    import java.io.DataInputStream;
    import java.io.DataOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.Socket;
    import java.util.Scanner;
     
    public class RecieveThread extends Thread {
     
        private Socket s;
     
        public RecieveThread(Socket s) {
            this.s = s;
        }
     
        public void run() {
            try {
                InputStream is = s.getInputStream();
     
                DataInputStream dis = new DataInputStream(is);
                while (true) {
                    String msg = dis.readUTF();
                    System.out.println(msg);
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
     
        }
     
    }
    package socket;
     
    import java.io.IOException;
    import java.net.ServerSocket;
    import java.net.Socket;
     
    public class Server {
     
        public static void main(String[] args) {
            try {
     
                ServerSocket ss = new ServerSocket(8888);
     
                System.out.println("监听在端口号:8888");
                Socket s = ss.accept();
     
                //启动发送消息线程
                new SendThread(s).start();
                //启动接受消息线程
                new RecieveThread(s).start();
     
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
     
        }
    }
    package socket;
     
    import java.io.IOException;
    import java.net.Socket;
    import java.net.UnknownHostException;
     
    public class Client {
     
        public static void main(String[] args) {
     
            try {
                Socket s = new Socket("127.0.0.1", 8888);
     
                // 启动发送消息线程
                new SendThread(s).start();
                // 启动接受消息线程
                new RecieveThread(s).start();
     
            } catch (UnknownHostException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
    或者用匿名类
    package socket1;
    
    import java.io.DataInputStream;
    import java.io.DataOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.Socket;
    import java.net.UnknownHostException;
    import java.util.Scanner;
    
    public class Client {
    
    	public static void main(String[] args) throws UnknownHostException,
    			IOException {
    		// TODO Auto-generated method stub
    		final Socket s = new Socket("127.0.0.1", 8888);
    		final OutputStream os = s.getOutputStream();
    		final DataOutputStream dos = new DataOutputStream(os);
    		final InputStream is = s.getInputStream();
    		final DataInputStream dis = new DataInputStream(is);
    		final Scanner sc = new Scanner(System.in);
    		try {
    			Thread t1 = new Thread() {
    				public void run() {
    					try {
    						while (true) {
    							String str = sc.next();
    							dos.writeUTF(str);
    						}
    					} catch (IOException e) {
    						// TODO Auto-generated catch block
    						e.printStackTrace();
    					}
    				}
    			};
    			t1.start();
    
    			Thread t2 = new Thread() {
    				public void run() {
    					try {
    						while (true) {
    							String msg = dis.readUTF();
    							System.out.println("Client: " + msg);
    						}
    					} catch (IOException e) {
    						// TODO Auto-generated catch block
    						e.printStackTrace();
    					}
    				}
    			};
    			t2.start();
    		} catch (Exception e) {
    			// TODO: handle exception
    			e.printStackTrace();
    		}
    	}
    }
    
    package socket1;
    
    import java.io.DataInputStream;
    import java.io.DataOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.Scanner;
    
    public class Server {
    
    	public static void main(String[] args) throws IOException {
    		// TODO Auto-generated method stub
    		final ServerSocket ss = new ServerSocket(8888);
    		final Socket s = ss.accept();
    		final InputStream is = s.getInputStream();
    		final DataInputStream dis = new DataInputStream(is);
    		final OutputStream os = s.getOutputStream();
    		final DataOutputStream dos = new DataOutputStream(os);
    		final Scanner sc = new Scanner(System.in);
    		
    		try {
    			Thread t1 = new Thread() {
    				@Override
    				public void run() {
    					// TODO Auto-generated method stub
    					while (true) {
    
    						try {
    							String msg = dis.readUTF();
    							System.out.println("Server: " + msg);
    						} catch (IOException e) {
    							// TODO Auto-generated catch block
    							e.printStackTrace();
    						}
    					}
    				}
    			};
    			t1.start();
    
    			Thread t2 = new Thread() {
    				@Override
    				public void run() {
    					// TODO Auto-generated method stub
    					while (true) {
    						try {
    							String str = sc.next();
    							dos.writeUTF(str);
    						} catch (IOException e) {
    							// TODO Auto-generated catch block
    							e.printStackTrace();
    						}
    					}
    				}
    			};
    			t2.start();
    
    		} catch (Exception e) {
    			// TODO: handle exception
    			e.printStackTrace();
    		}
    	}
    }
    











  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值