Android 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;

}

}

运行效果:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

以上是 Android Socket通信的简单实现 的全部内容, 来源链接: utcz.com/p/243959.html

回到顶部