Android Socket通信的简单实现
程序员文章站
2022-06-24 11:21:06
公司要实现一个简单的聊天功能,提前研究一下socket通信,而公司的服务端功能又没有实现,所以这里就把服务端的功能放到一个界面实现了。直接上代码:
公司要实现一个简单的聊天功能,提前研究一下socket通信,而公司的服务端功能又没有实现,所以这里就把服务端的功能放到一个界面实现了。
直接上代码:
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.constraintlayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".mainactivity"> <edittext android:id="@+id/et_ip" android:layout_width="0dp" android:layout_height="wrap_content" android:hint="ip:端口" android:text="127.0.0.1:8081" android:layout_margin="10dp" android:padding="10dp" app:layout_constraintleft_toleftof="parent" app:layout_constraintright_toleftof="@+id/btn_connect" app:layout_constrainttop_totopof="parent" /> <button android:id="@+id/btn_connect" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constrainttop_totopof="parent" app:layout_constraintright_torightof="parent" android:layout_margin="10dp" android:text="连接"/> <textview android:id="@+id/tv_receive" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="接受数据:" app:layout_constrainttop_tobottomof="@+id/et_ip" app:layout_constraintleft_toleftof="parent" android:textsize="14sp" android:layout_margin="10dp"/> <scrollview android:id="@+id/sv_content" android:layout_width="match_parent" android:layout_height="200dp" app:layout_constrainttop_tobottomof="@+id/tv_receive" app:layout_constraintleft_toleftof="parent"> <linearlayout android:layout_width="match_parent" android:layout_height="wrap_content"> <textview android:id="@+id/tv_content" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="聊天内容" android:textcolor="#000" android:textsize="16sp" android:layout_margin="10dp"/> </linearlayout> </scrollview> <edittext android:id="@+id/et_input" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="发送内容" android:layout_margin="10dp" android:padding="10dp" app:layout_constraintleft_toleftof="parent" app:layout_constrainttop_tobottomof="@+id/sv_content" /> <button android:id="@+id/btn_service" android:layout_width="0dp" android:layout_height="wrap_content" app:layout_constrainttop_tobottomof="@+id/et_input" app:layout_constraintleft_toleftof="parent" app:layout_constraintright_toleftof="@+id/btn_send" android:layout_margin="10dp" android:text="服务端发送"/> <button android:id="@+id/btn_send" android:layout_width="0dp" android:layout_height="wrap_content" app:layout_constrainttop_tobottomof="@+id/et_input" app:layout_constraintleft_torightof="@+id/btn_service" app:layout_constraintright_torightof="parent" android:layout_margin="10dp" android:text="发送"/> </androidx.constraintlayout.widget.constraintlayout>
主要代码:
package com.app.socketdemo; import android.annotation.suppresslint; import android.os.bundle; import android.os.handler; import android.os.message; import android.text.html; import android.text.textutils; import android.view.view; import android.widget.button; import android.widget.edittext; import android.widget.scrollview; import android.widget.textview; import android.widget.toast; import java.io.datainputstream; import java.io.dataoutputstream; import java.io.ioexception; import java.io.inputstream; import java.io.outputstream; import java.net.inetaddress; import java.net.serversocket; import java.net.socket; import androidx.appcompat.app.appcompatactivity; import butterknife.bindview; import butterknife.butterknife; import butterknife.onclick; public class mainactivity extends appcompatactivity { @bindview(r.id.et_ip) edittext etip; @bindview(r.id.btn_connect) button btnconnect; @bindview(r.id.tv_receive) textview tvreceive; @bindview(r.id.tv_content) textview tvcontent; @bindview(r.id.et_input) edittext etinput; @bindview(r.id.btn_send) button btnsend; @bindview(r.id.sv_content) scrollview svcontent; @bindview(r.id.btn_service) button btnservice; private stringbuffer strmsg = new stringbuffer(); private final int message_error = 0; private final int message_succeed = 1; private final int message_receive = 2; private socket sock; private outputstream outx; private inputstream inx; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); butterknife.bind(this); //启动服务端 new thread(() -> new server().startservice()).start(); } @onclick({r.id.btn_connect, r.id.btn_service, r.id.btn_send}) public void onviewclicked(view view) { switch (view.getid()) { case r.id.btn_connect://连接服务端 string strip = etip.gettext().tostring().trim(); if (strip.indexof(":") >= 0) { //启动连接 new socket_thread(strip).start(); } break; case r.id.btn_service: if (!textutils.isempty(etinput.gettext().tostring())) { sendstring("服务端:" + etinput.gettext().tostring().trim()); etinput.settext(""); } else { toast.maketext(this, "输入不可为空", toast.length_short).show(); } break; case r.id.btn_send: if (!textutils.isempty(etinput.gettext().tostring())) { sendstrsocket("客户端:" + etinput.gettext().tostring().trim()); etinput.settext(""); } else { toast.maketext(this, "输入不可为空", toast.length_short).show(); } break; } } /** * 连接服务器 */ class socket_thread extends thread { private string ip = "";//ip地址 private int port = 0;//端口号 public socket_thread(string strip) { //如: 127.0.0.1:8081 string[] stripx = strip.split(":"); this.ip = stripx[0]; this.port = integer.parseint(stripx[1]); } @override public void run() { try { dissocket(); //连接服务器,此处会一直处于阻塞,直到连接成功 sock = new socket(this.ip, this.port); //阻塞停止,表示连接成功 setmessage("连接成功", message_succeed); } catch (exception e) { setmessage("连接服务器时异常", message_error); e.printstacktrace(); return; } try { //获取到输入输出流 outx = sock.getoutputstream(); inx = sock.getinputstream(); } catch (exception e) { setmessage("获取输入输出流异常", message_error); e.printstacktrace(); return; } new inx().start(); } } /** * 循环接收数据 */ class inx extends thread { @override public void run() { while (true) { byte[] bu = new byte[1024]; try { int conut = inx.read(bu);//设备重启,异常 将会一直停留在这 if (conut == -1) { setmessage("服务器断开", message_error); dissocket(); return; } string strread = new string(bu, "gbk").trim(); setmessage(strread, message_receive); } catch (ioexception e) { system.out.println(e); } } } } /** * 断开连接 */ private void dissocket() { if (sock != null) { try { outx.close(); inx.close(); sock.close(); sock = null; } catch (exception e) { setmessage("断开连接时发生错误", message_error); } } } @suppresslint("handlerleak") private handler handler = new handler() { @override public void handlemessage(message msg) { switch (msg.arg1) { case message_error: dissocket(); strmsg.append(msg.obj + "<br>"); tvcontent.settext(html.fromhtml(strmsg.tostring())); break; case message_succeed: strmsg.append(msg.obj + "<br>"); tvcontent.settext(html.fromhtml(strmsg.tostring())); break; case message_receive: //收到数据 strmsg.append(msg.obj); if (!strmsg.tostring().substring(strmsg.length() - 4, strmsg.length()).equals("<br>")) { strmsg.append("<br>"); } tvcontent.settext(html.fromhtml(strmsg.tostring())); svcontent.fullscroll(scrollview.focus_down); break; default: break; } } }; /** * 发送消息 */ private void sendstrsocket(final string senddata) { new thread(new runnable() { @override public void run() { try { string str = "<font color='#ee2c2c'>" + senddata + "</font>"; outx.write(str.getbytes("gbk"));//"utf-8" } catch (exception e) { setmessage("数据发送异常", message_error); } } }).start(); } /** * 消息处理 */ private void setmessage(string obj, int arg1){ message message = new message(); message.arg1 = arg1; message.obj = obj; handler.sendmessage(message); } /*************************************************************服务端(用于测试)**********************************************************************/ private string msg = ""; public class server { serversocket serversocket = null; public final int port = 8081; public server() { //输出服务器的ip地址 try { inetaddress addr = inetaddress.getlocalhost(); serversocket = new serversocket(port); } catch (ioexception e) { e.printstacktrace(); } } public void startservice() { try { while (true) { socket socket = null; socket = serversocket.accept();//等待一个客户端的连接,在连接之前,此方法是阻塞的 new connectthread(socket).start(); new connectthread1(socket).start(); } } catch (ioexception e) { e.printstacktrace(); } } /** * 向客户端发送信息 */ class connectthread extends thread { socket socket = null; public connectthread(socket socket) { super(); this.socket = socket; } @override public void run() { try { dataoutputstream out = new dataoutputstream(socket.getoutputstream()); while (true) { thread.sleep(1000); if (!textutils.isempty(msg)) { string str = "<font color='#4f94cd'>" + msg + "</font>"; out.write(str.getbytes("gbk")); out.flush(); msg = ""; } } } catch (ioexception e) { e.printstacktrace(); } catch (interruptedexception e) { e.printstacktrace(); } } } /** * 接收客户端信息 */ class connectthread1 extends thread { socket socket = null; public connectthread1(socket socket) { super(); this.socket = socket; } @override public void run() { try { datainputstream inp = new datainputstream(socket.getinputstream()); while (true) { byte[] bu = new byte[1024]; int conut = inp.read(bu);//设备重启,异常 将会一直停留在这 if (conut == -1) { setmessage("服务器断开", message_error); return; } string strread = new string(bu, "gbk").trim(); setmessage(strread, message_receive); } } catch (ioexception e) { e.printstacktrace(); } } } } private void sendstring(string str) { msg = str; } }
运行效果:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: 使用MUI框架实现JQ购物车增减