Android基于TCP协议的Socket通信完整聊天室例子(二)(记录学习)

今天又是元气满满学习的一天,从上章内容我们可以对socket tcp协议服务端和客户端的简单的信息传递接收进行学习,对socket通信有了一丢丢的了解,
流程图:
在这里插入图片描述
总结:tcp socket通信主要是再InputStream 和 OutputStream之间进行数据的读取和写入
其中我们可以通过 socket.getInputStream() 或者 socket.getOutputStream()拿到实例 然后进行读取和写入的功能
其中 socket.getInputStream()为输入流(读取) 收到的数据在这里
socket.getOutputStream()为输出流(写入) 发送的数据在这里

好了,废话不多比比 开始我们的简易聊天室的实现 —> 详细的实现请看代码中的注释
eclipse 服务端

public class Server {
    
	public static final int PORT = 12345;//端口号
	private List<Socket> mList = new ArrayList<Socket>();
	private ServerSocket server = null;
	private ExecutorService myExecutorService = null;
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
      new Server();
	}
	
	public Server(){
		//服务器创建流程如下
		try {
			//1.创建ServerSocket
			server = new ServerSocket(PORT);
			//创建线程池
			myExecutorService = Executors.newCachedThreadPool(); 
			System.out.println("服务端运行中...\n");
			Socket client = null;
			while(true)
			{
				//2.等待接收请求   这里接收客户端的请求
				client = server.accept();
				System.out.println("得到客户端连接:" + client);  
				mList.add(client);
				//初始化完成
				
				//执行线程
				myExecutorService.execute(new Service(client));
			}
			

		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
	
	class Service implements Runnable{
		private Socket socket;
		private BufferedReader in = null;
		private String msg = "";
		
		public Service(Socket socket){
			this.socket = socket;
			try {
				//3.接收请求后创建链接socket
				//4.通过InputStream  outputStream进行通信
				in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
				//可拆分
//				InputStream is = socket.getInputStream();
//				
//				InputStreamReader ins = new InputStreamReader(is);
//				
//				in = new BufferedReader(ins);
				
				 msg = "用户:" +this.socket.getInetAddress() + "~加入了聊天室"  
	                        +"当前在线人数:" +mList.size();  
				this.sendmsg();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
		
		@Override
		public void run() {
			// TODO Auto-generated method stub
			while(true){
				try {
					if((msg=in.readLine())!=null){
						System.out.println("从客户端接收到的消息为:" + msg);  
						if(msg.equals("bye")){
							System.out.println("~~~~~~~~~~~~~");
							mList.remove(socket);
                            in.close();
                            msg = "用户:" + socket.getInetAddress()  
                            + "退出:" +"当前在线人数:"+mList.size();  
                            //5.关闭资源
                            socket.close(); 
                            this.sendmsg();  
                            break;
						}else{
							msg = socket.getInetAddress() + "   说: " + msg;  
                            this.sendmsg(); 
						}
					}
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		

		//为连接上服务端的每个客户端发送信息
		public void sendmsg()
		{
			System.out.println(msg);
			int num = mList.size();
			for(int index = 0;index < num;index++)
			{
				Socket mSocket = mList.get(index);  
                PrintWriter pout = null;  
                try {  
                	//PrintWriter 和BufferWriter使用方法相似
                    pout = new PrintWriter(new BufferedWriter(  
                            new OutputStreamWriter(mSocket.getOutputStream(),"UTF-8")),true);  
                    pout.println(msg);  //将输出流包装为打印流
                }catch (IOException e) {e.printStackTrace();}  
			}
		}

	}
		
	
}

从上面的服务器端我们可以知道服务器端先将客户端发送的数据进行存储到msg中 然后通过PrintWriter 又发送到了客户端
PrintWriter 详解:

                //PrintWriter 和BufferWriter使用区别
                    BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));

                            bufw.write("hello,server!");

                            bufw.newLine();

                            bufw.flush();

                    //上面的4行代码用PrintWriter实现只需要两行。

             

                    PrintWtriter out = new PrintWriter(s.getOutputStream, true);
                    out.println("hello,server!");

安卓客户端

public class ChatRoom extends AppCompatActivity implements Runnable{
    //定义相关变量,完成初始化
    private TextView txtshow;
    private EditText editsend;
    private Button btnsend;
    private static final String HOST = "192.168.30.83";
    private static final int PORT = 12345;
    private Socket socket = null;
    private BufferedReader in = null;
    private PrintWriter out = null;
    private String content = "";
    private StringBuilder sb = null;

    //定义一个handler对象,用来刷新界面
    public Handler handler = new Handler() {
        public void handleMessage(Message msg) {
            if (msg.what == 0x123) {
                sb.append(content);
                Log.i("wotainanl","@@"+sb);
                txtshow.setText(sb.toString());
            }
        }

        ;
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_chat_room);
        sb = new StringBuilder();
        txtshow =  findViewById(R.id.txtshow);
        editsend =  findViewById(R.id.editsend);
        btnsend =  findViewById(R.id.btnsendza);

        //当程序一开始运行的时候就实例化Socket对象,与服务端进行连接,获取输入输出流
        new Thread() {

            public void run() {
                try {
                    socket = new Socket(HOST, PORT);
                    //获取输入输出流
                    in = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));
                    out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(
                            socket.getOutputStream())), true);
                    Log.i("wotainanl","in"+in+"@@"+out);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }.start();

       // 为发送按钮设置点击事件
        btnsend.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                final String msg = editsend.getText().toString();
                if (socket.isConnected()) {
                    if (!socket.isOutputShutdown()) {
                        new Thread(new Runnable() {
                            @Override
                            public void run() {
                                out.println(msg);
                            }
                        }).start();
                        Log.i("wotainanl",msg);
                    }
                }
            }
        });
        new Thread(ChatRoom.this).start();
    }

    //重写run方法,在该方法中输入流的读取
    @Override
    public void run() {
        try {
            while (true) {
                if (socket.isConnected()) {
                    if (!socket.isInputShutdown()) {
                        if ((content = in.readLine()) != null) {
                            content += "\n";
                            handler.sendEmptyMessage(0x123);
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

在这里插入图片描述
over!
Socket TCP的通信流程:
传输前先开服务端,accept,等客户端接入,然后获得 客户端socket然后进行IO操作

本文参考:https://www.kancloud.cn/kancloud/android-tutorial/87240

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

安东尼肉店

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值