专栏首页恩蓝脚本Android中socket通信的简单实现

Android中socket通信的简单实现

Android中socket通信简单实现,供大家参考,具体内容如下

socket通信需要有一个服务器和客户端,可以把同一个APP作为服务器跟客户端,也可以分开成两个APP。 先上个图:

这里以一个APP作为服务器跟客户端为示例

1、添加网络访问权限

<uses-permission android:name="android.permission.INTERNET" / 

2、写服务器,在APP上启动

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {

 ServerSocket serverSocket = null;
 public final int port = 9998;
 private int i = 0;

 public Server(){

  //输出服务器的IP地址
  try {
   InetAddress addr = InetAddress.getLocalHost();
   System.out.println("local host:"+addr);
   serverSocket = new ServerSocket(port);
   System.out.println("0k");
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }

 public void startService(){

  try {
   Socket socket = null;
   System.out.println("waiting...");
   //等待连接,每建立一个连接,就新建一个线程
   while(true){
    socket = serverSocket.accept();//等待一个客户端的连接,在连接之前,此方法是阻塞的
    System.out.println("connect to"+socket.getInetAddress()+":"+socket.getLocalPort());
    new ConnectThread(socket).start();
   }

  } catch (IOException e) {
   // TODO Auto-generated catch block
   System.out.println("IOException");
   e.printStackTrace();
  }
 }

 //向客户端发送信息
 class ConnectThread extends Thread{
  Socket socket = null;

  public ConnectThread(Socket socket){
   super();
   this.socket = socket;
  }

  @Override
  public void run(){
   try {
    DataInputStream dis = new DataInputStream(socket.getInputStream());
    DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
    while(true){
     i++;
     String msgRecv = dis.readUTF();
     System.out.println("msg from client:"+msgRecv);
     dos.writeUTF(msgRecv + i);
     dos.flush();
    }
   } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
  }
 }
}

需要在线程中调用,调用方法:

new Thread(() -  new Server().startService()).start();

3、客户端代码

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import androidx.appcompat.app.AppCompatActivity;
/**
* @author fenghaitao
* @time 2020年4月2日14:34:33
* scoket客户端连接测试
*/
public class SocketActivity extends AppCompatActivity {
//IP地址和端口号
public static String IP_ADDRESS = "";
public static int PORT = 9998;
//三个控件
EditText et_message = null; //需要发送的内容
Button bt_getAdress = null; //获取本机IP地址
Button bt_connect = null; //连接并发送
Button bt_startServer = null; //启动服务端
TextView tv_adress = null; //ip地址
TextView tv_reply = null; //服务器回复的消息
//handler
Handler handler = null;
Socket soc = null;
DataOutputStream dos = null;
DataInputStream dis = null;
String messageRecv = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_socket);
et_message = findViewById(R.id.et_message);
bt_getAdress = findViewById(R.id.bt_getAdress);
bt_connect = findViewById(R.id.bt_connect);
bt_startServer = findViewById(R.id.bt_startServer);
tv_adress = findViewById(R.id.tv_adress);
tv_reply = findViewById(R.id.tv_reply);
bt_getAdress.setOnClickListener(v -  {
new Thread(() -  {
try {
InetAddress addr = InetAddress.getLocalHost();
System.out.println("local host:"+addr);
runOnUiThread(() -  tv_adress.setText(addr.toString().split("/")[1]));
} catch (UnknownHostException e) {
e.printStackTrace();
}
}).start();
});
bt_startServer.setOnClickListener(v -  {
new Thread(() -  new Server().startService()).start();
Toast.makeText(SocketActivity.this,"服务已启动",Toast.LENGTH_SHORT).show();
});
bt_connect.setOnClickListener(v -  {
IP_ADDRESS = tv_adress.getText().toString();
new ConnectionThread(et_message.getText().toString()).start();
});
handler = new Handler(msg -  {
Bundle b = msg.getData(); //获取消息中的Bundle对象
String str = b.getString("data"); //获取键为data的字符串的值
tv_reply.append(str);
return false;
});
}
//新建一个子线程,实现socket通信
class ConnectionThread extends Thread {
String message = null;
public ConnectionThread(String msg) {
message = msg;
}
@Override
public void run() {
if (soc == null) {
try {
//Log.d("socket","new socket");
if ("".equals(IP_ADDRESS)) {
return;
}
soc = new Socket(IP_ADDRESS, PORT);
//获取socket的输入输出流
dis = new DataInputStream(soc.getInputStream());
dos = new DataOutputStream(soc.getOutputStream());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
dos.writeUTF(message);
dos.flush();
messageRecv = dis.readUTF();//如果没有收到数据,会阻塞
Message msg = new Message();
Bundle b = new Bundle();
b.putString("data", messageRecv);
msg.setData(b);
handler.sendMessage(msg);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}

下面是xml页面代码

<?xml version="1.0" encoding="utf-8"? 
<LinearLayout 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=".SocketActivity" 
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" 
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp" 
<Button
android:id="@+id/bt_getAdress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="获取IP地址"/ 
<TextView
android:id="@+id/tv_adress"
android:layout_width="200dp"
android:layout_height="match_parent"
android:layout_marginLeft="15dp"
android:textSize="20dp"
android:gravity="center"/ 
</LinearLayout 
<Button
android:id="@+id/bt_startServer"
android:text="启动服务"
android:layout_marginTop="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/ 
<EditText
android:id="@+id/et_message"
android:layout_marginTop="10dp"
android:hint="请输入发送信息"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/ 
<Button
android:id="@+id/bt_connect"
android:text="连接发送"
android:layout_marginTop="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/ 
<TextView
android:id="@+id/tv_reply"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="服务端返回消息:"
android:textSize="30sp"/ 
</LinearLayout 
</LinearLayout 

客户端跟服务器进行通信之前记得先启动服务器,如果端口被占用需要换个端口。

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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Android实现类似execel的表格 能回显并能修改表格内容的方法

    以上这篇Android实现类似execel的表格 能回显并能修改表格内容的方法就是小编分享给大家的全部内容了,希望能给大家一个参考。

    砸漏
  • Android自定View流式布局根据文字数量换行

    本文实例为大家分享了Android根据文字数量换行的具体代码,供大家参考,具体内容如下

    砸漏
  • FragmentTabHost使用方法详解

    FragmentTabHost是support-v包下提供的用于集成和管理Fragment页面的组件.

    砸漏
  • [android] post请求接口demo测试代码

    陶士涵
  • Android 设备唯一标识(适配Android版本)

      相信在看这篇文章之前你已经看过一些类似的文章了,那么你肯定知道自己想要的是什么。

    晨曦_LLW
  • 安卓开发_慕课网_Fragment实现Tab(App主界面)

    听着music睡
  • Android实现类似execel的表格 能回显并能修改表格内容的方法

    以上这篇Android实现类似execel的表格 能回显并能修改表格内容的方法就是小编分享给大家的全部内容了,希望能给大家一个参考。

    砸漏
  • 安卓 —— 图灵机器人+讯飞语音设计实现

    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011415782/article/de...

    泥豆芽儿 MT
  • 保存手写签名

    Android 提供了很多丰富、实用而且很有特色的功能。比如,语音识别、手写签名等等。本篇就为你介绍如何在android上进行个性化的手写签名。 首先大致说...

    xiangzhihong
  • 3.PopupWindow 、拍照、裁剪

    六月的雨

扫码关注云+社区

领取腾讯云代金券