android基于socket的局域网内服务器与客户端加密通信

实现了基本的socket通信(即两台设备,一台用作服务器,一台用作客户端),服务器进行监听,客户端发送加密数据到服务器,服务器进行解密得到明文。

注意:本项目中使用了ButterKnife及EventBus作为辅助工具,通信建立时默认网络正常(未做局域网网络环境检测),加密方式为AES加密

1.效果图:

(1)客户端

(2)服务器端

2.界面布局部分

(1)服务器端布局 function_socket_server.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:orientation="vertical">

 <RelativeLayout style="@style/ToolBar">

  <TextView
   style="@style/ToolBar_tv_Title"
   android:text="网络加密-服务器端" />

 </RelativeLayout>

 <LinearLayout
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:orientation="horizontal">

  <Button
   android:id="@+id/btn_startListener"
   android:layout_width="0dp"
   android:layout_height="wrap_content"
   android:layout_weight="1"
   android:text="启动监听" />

  <Button
   android:id="@+id/btn_stopListener"
   android:layout_width="0dp"
   android:layout_height="wrap_content"
   android:layout_weight="1"
   android:text="停止监听" />

  <Button
   android:id="@+id/btn_getUser"
   android:layout_width="0dp"
   android:layout_height="wrap_content"
   android:layout_weight="1"
   android:text="刷新用户" />
 </LinearLayout>

 <LinearLayout
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:orientation="horizontal"
  android:padding="10dp">

  <TextView
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:text="本机地址:" />

  <TextView
   android:id="@+id/tv_localAddress"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:singleLine="true" />
 </LinearLayout>

 <ScrollView
  android:layout_width="match_parent"
  android:layout_height="match_parent">

  <LinearLayout
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:orientation="vertical">

   <TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="接收到的明文:"
    android:textColor="@color/black" />

   <TextView
    android:id="@+id/tv_receivedContent"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="10dp" />

   <TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="解密后的明文:"
    android:textColor="@color/black" />

   <TextView
    android:id="@+id/tv_decryptContent"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="10dp" />
  </LinearLayout>

 </ScrollView>

</LinearLayout>

(2)客户端布局 function_socket_client.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:orientation="vertical">

 <RelativeLayout style="@style/ToolBar">

  <TextView
   style="@style/ToolBar_tv_Title"
   android:text="网络加密-客户端" />

 </RelativeLayout>

 <LinearLayout
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:orientation="horizontal"
  android:padding="10dp">

  <TextView
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:text="服务器地址:" />

  <EditText
   android:id="@+id/edtTxt_serverAddress"
   android:layout_width="match_parent"
   android:text="192.168.43.1"
   android:layout_height="wrap_content"
   android:singleLine="true" />
 </LinearLayout>

 <ScrollView
  android:layout_width="match_parent"
  android:layout_height="0dp"
  android:layout_weight="1">

  <LinearLayout
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:orientation="vertical">

   <TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="文本内容:"
    android:textColor="@color/black" />

   <EditText
    android:id="@+id/edtTxt_Content"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/main_background"
    android:padding="10dp"
    android:text="123木头人" />
  </LinearLayout>
 </ScrollView>

 <Button
  android:id="@+id/btn_encryptAndSend"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:layout_gravity="bottom"
  android:text="加密并发送" />
</LinearLayout>

(3)用到的style

 <!--通用Title的右侧按钮-->
 <style name="ToolBar_iv_Right">
  <item name="android:layout_width">@dimen/toolbar_icon_dimen</item>
  <item name="android:layout_height">@dimen/toolbar_icon_dimen</item>
  <item name="android:layout_alignParentRight">true</item>
  <item name="android:layout_gravity">end</item>
  <item name="android:clickable">true</item>
  <item name="android:background">?android:actionBarItemBackground</item>
  <item name="android:padding">15dp</item>
 </style>
 <!--通用Title的TextView-->
 <style name="ToolBar_tv_Title">
  <item name="android:layout_width">wrap_content</item>
  <item name="android:layout_height">wrap_content</item>
  <item name="android:layout_centerVertical">true</item>
  <item name="android:layout_marginLeft">@dimen/toolbar_title_haveBack_marginStart</item>
  <item name="android:layout_marginRight">@dimen/toolbar_title_haveBack_marginEnd</item>
  <item name="android:gravity">center</item>
  <item name="android:singleLine">true</item>
  <item name="android:textColor">@color/white</item>
  <item name="android:textSize">20sp</item>
 </style>

3.功能代码

(1)基类 BaseEventActivity.Java

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;

import org.greenrobot.eventbus.EventBus;

import butterknife.ButterKnife;

public abstract class BaseEventActivity extends AppCompatActivity {
 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  getIntentData();
  setContentView(getLayoutResId());
  ButterKnife.bind(this);
  EventBus.getDefault().register(this);
  init();
 }

 protected void getIntentData() {
 }

 @Override
 protected void onDestroy() {
  super.onDestroy();
  EventBus.getDefault().unregister(this);
 }

 protected abstract void init();

 protected abstract int getLayoutResId();
}

(2)服务器主界面 Function_Socket.java

import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.view.View;
import android.widget.TextView;

import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;

import butterknife.BindView;
import butterknife.OnClick;

/**
 * 服务器界面
 */
public class Function_Socket_Server extends BaseEventActivity {
 @BindView(R.id.tv_localAddress)
 TextView tv_localAddress;
 @BindView(R.id.tv_receivedContent)
 TextView tv_receivedContent;
 @BindView(R.id.tv_decryptContent)
 TextView tv_decryptContent;
 private LocalService localService;//用于启动监听的服务
 private ServiceConnection sc;//服务连接

 @Override
 protected void init() {
  tv_localAddress.setText(ToolUtil.getHostIP());
  sc = new ServiceConnection() {
   @Override
   public void onServiceConnected(ComponentName name, IBinder service) {
    LocalService.LocalBinder localBinder = (LocalService.LocalBinder) service;
    localService = localBinder.getService();
    localService.startWaitDataThread();
    ToastUtil.showToast(Function_Socket_Server.this, "监听已启动");
   }

   @Override
   public void onServiceDisconnected(ComponentName name) {
   }
  };
  connection();
 }

 @Subscribe(threadMode = ThreadMode.MAIN)
 public void getData(String data) {
  tv_receivedContent.setText(data);
  tv_decryptContent.setText(AESUtil.decrypt(ConstantUtil.password, data));
 }

 /**
  * 绑定service
  */
 private void connection() {
  Intent intent = new Intent(this, LocalService.class);
  bindService(intent, sc, BIND_AUTO_CREATE);
 }

 @Override
 protected int getLayoutResId() {
  return R.layout.function_socket_server;
 }

 /**
  * 获取连接到本机热点上的手机ip
  */
 private ArrayList<String> getConnectedIP() {
  ArrayList<String> connectedIP = new ArrayList<>();
  try {
   //通过读取配置文件实现
   BufferedReader br = new BufferedReader(new FileReader(
     "/proc/net/arp"));
   String line;
   while ((line = br.readLine()) != null) {
    String[] splitted = line.split(" +");
    if (splitted.length >= 4) {
     String ip = splitted[0];
     connectedIP.add(ip);
    }
   }
  } catch (Exception e) {
   e.printStackTrace();
  }
  return connectedIP;
 }

 @OnClick({R.id.btn_startListener, R.id.btn_stopListener, R.id.btn_getUser})
 public void onClick(View v) {
  switch (v.getId()) {
   case R.id.btn_startListener://启动监听
    connection();
    break;
   case R.id.btn_stopListener://停止监听
    if (sc != null)
     unbindService(sc);
    break;
   case R.id.btn_getUser://刷新连接到此设备的IP并清空之前接收到的数据
    ArrayList<String> connectedIP = getConnectedIP();
    StringBuilder resultList = new StringBuilder();

    for (String ip : connectedIP) {
     resultList.append(ip);
     resultList.append("\n");
    }
    ToastUtil.showToast(this, "连接到手机上的Ip是:" + resultList.toString());
    tv_decryptContent.setText("");
    tv_receivedContent.setText("");
    break;
  }
 }

 public void onDestroy() {
  super.onDestroy();
  if (sc != null)
   unbindService(sc);
 }

}

(3)客户端主界面 Function_Socket_Client.java

import android.app.ProgressDialog;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import butterknife.BindView;
import butterknife.OnClick;

/**
 * 客户端界面
 */
public class Function_Socket_Client extends BaseEventActivity {
 @BindView(R.id.edtTxt_Content)
 EditText edtTxt_Content;
 @BindView(R.id.edtTxt_serverAddress)
 EditText edtTxt_serverAddress;

 private ProgressDialog mProgressDialog;//加载的小菊花

 /**
  * 初始化
  */
 @Override
 protected void init() {
 }

 @Override
 protected int getLayoutResId() {
  return R.layout.function_socket_client;
 }

 @OnClick(R.id.btn_encryptAndSend)
 public void onClick(View v) {
  switch (v.getId()) {
   case R.id.btn_encryptAndSend:
    String s = edtTxt_Content.getText().toString().trim();
    String ip = edtTxt_serverAddress.getText().toString().trim();
    if (ToolUtil.IsIpv4(ip)) {
     new SendDataThread(ip, AESUtil.encrypt(ConstantUtil.password, s), ConstantUtil.port).start();//消息发送方启动线程发送消息
     showProgressDialog("尝试发送数据到\n\t\t" + ip, true);
    } else {
     ToastUtil.showToast(this, "IP不合法!");
    }
    break;
  }
 }

 /**
  * 连接结果
  *
  * @param resultCode 0:连接超时;1:发送成功 2:失败
  */
 @Subscribe(threadMode = ThreadMode.MAIN)
 public void sendResult(Integer resultCode) {
  Log.i("succ", "=" + resultCode);
  dismissProgressDialog();
  switch (resultCode) {
   case ConstantUtil.CODE_SUCCESS:
    ToastUtil.showToast(this, "发送成功");
    break;
   case ConstantUtil.CODE_TIMEOUT:
    ToastUtil.showToast(this, "连接超时");
    break;
   case ConstantUtil.CODE_UNKNOWN_HOST:
    ToastUtil.showToast(this, "错误-未知的host");
    break;

  }

 }

 /**
  * 数据加载小菊花
  *
  * @param msg  内容
  * @param isCancel 是否允许关闭 true - 允许 false - 不允许
  */
 public void showProgressDialog(final String msg, final boolean isCancel) {
  runOnUiThread(new Runnable() {
   @Override
   public void run() {
    try {
     if (mProgressDialog == null) {
      mProgressDialog = new ProgressDialog(Function_Socket_Client.this);
     }
     if (mProgressDialog.isShowing()) {
      return;
     }
     mProgressDialog.setMessage(msg);
     mProgressDialog.setCancelable(isCancel);
     mProgressDialog.setCanceledOnTouchOutside(false);
     mProgressDialog.setOnCancelListener(null);
     mProgressDialog.show();
    } catch (Exception e) {
     e.printStackTrace();
    }
   }
  });
 }

 /**
  * 隐藏数据加载的进度小菊花
  **/
 public void dismissProgressDialog() {

  try {
   if (mProgressDialog != null && mProgressDialog.isShowing()) {
    runOnUiThread(
      new Runnable() {
       @Override
       public void run() {
        mProgressDialog.dismiss();
       }
      }
    );
   }
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
}

(4)LocalService.java

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;

/**
 * 此服务用于启动监听线程
 */
public class LocalService extends Service {
 private IBinder iBinder = new LocalService.LocalBinder();

 @Override
 public IBinder onBind(Intent intent) {
  return iBinder;
 }

 @Override
 public int onStartCommand(Intent intent, int flags, int startId) {
  return START_STICKY;
 }

 public void startWaitDataThread() {
  new ListenThread(ConstantUtil.port).start();
 }

 //定义内容类继承Binder
 public class LocalBinder extends Binder {
  //返回本地服务
  public LocalService getService() {
   return LocalService.this;
  }
 }
}

(5)ListenThread.java

import org.greenrobot.eventbus.EventBus;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 监听线程
 */
public class ListenThread extends Thread {
 private ServerSocket serverSocket;

 public ListenThread(int port) {
  try {
   serverSocket = new ServerSocket(port);
  } catch (IOException e) {
   e.printStackTrace();
  }
 }

 @Override
 public void run() {
  while (true) {
   try {
    if (serverSocket != null) {
     Socket socket = serverSocket.accept();
     InputStream inputStream = socket.getInputStream();
     if (inputStream != null) {
      BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
      String str;
      str = in.readLine();
      EventBus.getDefault().post(str);
      socket.close();
     }
    }
   } catch (IOException e) {
    e.printStackTrace();
   }

  }
 }
}

(6)SendDataThread.java

import android.util.Log;

import org.greenrobot.eventbus.EventBus;

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;

/**
 * 数据发送线程
 */
public class SendDataThread extends Thread {
 private Socket socket;
 private String ip;//接收方的IP
 private int port;//接收方的端口号
 private String data;//准备发送的数据

 public SendDataThread(String ip, String data, int port) {
  this.ip = ip;
  this.data = data;
  this.port = port;
 }

 @Override
 public void run() {
  try {
   socket = new Socket();
   socket.connect(new InetSocketAddress(ip,port),ConstantUtil.TIME_MILLIS);//设置超时时间
  } catch (UnknownHostException e) {
   EventBus.getDefault().post(ConstantUtil.CODE_UNKNOWN_HOST);
   Log.d("error", "SendDataThread.init() has UnknownHostException" + e.getMessage());
  } catch (SocketTimeoutException e) {
   EventBus.getDefault().post(ConstantUtil.CODE_TIMEOUT);
   Log.d("error", "SendDataThread.init() has TimeoutException:" + e.getMessage());
  }catch (IOException e){
   Log.d("error", "SendDataThread.init() has IOException:" + e.getMessage());
  }
  if (socket != null&&socket.isConnected()) {
   try {
    OutputStream ops = socket.getOutputStream();
    OutputStreamWriter opsw = new OutputStreamWriter(ops);
    BufferedWriter writer = new BufferedWriter(opsw);
    writer.write(data + "\r\n\r\n");//由于socket使用缓冲区进行读写数据,因此使用\r\n\r\n用于表明数据已写完.不加这个会导致数据无法发送
    EventBus.getDefault().post(ConstantUtil.CODE_SUCCESS);
    writer.flush();
   } catch (IOException e) {
    e.printStackTrace();
   }
  }

 }
}

(7)AESUtil.java

import android.util.Log;

import java.io.UnsupportedEncodingException;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

/**
 * AES加密工具类
 */
public class AESUtil {

 // private static final String CipherMode = "AES/ECB/PKCS5Padding";使用ECB加密,不需要设置IV,但是不安全
 private static final String CipherMode = "AES/CFB/NoPadding";//使用CFB加密,需要设置IV

 /**
  * 生成加密后的密钥
  *
  * @param password 密钥种子
  * @return isSucceed
  */
 private static SecretKeySpec createKey(String password) {
  byte[] data = null;
  if (password == null) {
   password = "";
  }
  StringBuilder sb = new StringBuilder(32);
  sb.append(password);
  while (sb.length() < 32) {
   sb.append("0");
  }
  if (sb.length() > 32) {
   sb.setLength(32);
  }

  try {
   data = sb.toString().getBytes("UTF-8");
  } catch (UnsupportedEncodingException e) {
   e.printStackTrace();
  }
  return new SecretKeySpec(data, "AES");
 }

 // /** 加密字节数据 **/
 private static byte[] encrypt(byte[] content, String password) {
  try {
   SecretKeySpec key = createKey(password);
   System.out.println(key);
   Cipher cipher = Cipher.getInstance(CipherMode);
   cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(
     new byte[cipher.getBlockSize()]));
   return cipher.doFinal(content);
  } catch (Exception e) {
   e.printStackTrace();
  }
  return null;
 }

 // /** 加密(结果为16进制字符串) **/
 public static String encrypt(String password, String content) {
  Log.d("加密前", "seed=" + password + "\ncontent=" + content);
  byte[] data = null;
  try {
   data = content.getBytes("UTF-8");
  } catch (Exception e) {
   e.printStackTrace();
  }
  data = encrypt(data, password);
  String result = byte2hex(data);
  Log.d("加密后", "result=" + result);
  return result;
 }

 // /** 解密字节数组 **/
 private static byte[] decrypt(byte[] content, String password) {

  try {
   SecretKeySpec key = createKey(password);
   Cipher cipher = Cipher.getInstance(CipherMode);
   cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(
     new byte[cipher.getBlockSize()]));

   return cipher.doFinal(content);
  } catch (Exception e) {
   e.printStackTrace();
  }
  return null;
 }

 // /** 解密16进制的字符串为字符串 **/
 public static String decrypt(String password, String content) {
  Log.d("解密前", "seed=" + password + "\ncontent=" + content);
  byte[] data = null;
  try {
   data = hex2byte(content);
  } catch (Exception e) {
   e.printStackTrace();
  }
  data = decrypt(data, password);
  if (data == null)
   return null;
  String result = null;
  try {
   result = new String(data, "UTF-8");
   Log.d("解密后", "result=" + result);
  } catch (UnsupportedEncodingException e) {
   e.printStackTrace();
  }
  return result;
 }

 // /** 字节数组转成16进制字符串 **/
 private static String byte2hex(byte[] b) { // 一个字节的数,
  StringBuilder sb = new StringBuilder(b.length * 2);
  String tmp ;
  for (byte aB : b) {
   // 整数转成十六进制表示
   tmp = (Integer.toHexString(aB & 0XFF));
   if (tmp.length() == 1) {
    sb.append("0");
   }
   sb.append(tmp);
  }
  return sb.toString().toUpperCase(); // 转成大写
 }

 // /** 将hex字符串转换成字节数组 **/
 private static byte[] hex2byte(String inputString) {
  if (inputString == null || inputString.length() < 2) {
   return new byte[0];
  }
  inputString = inputString.toLowerCase();
  int l = inputString.length() / 2;
  byte[] result = new byte[l];
  for (int i = 0; i < l; ++i) {
   String tmp = inputString.substring(2 * i, 2 * i + 2);
   result[i] = (byte) (Integer.parseInt(tmp, 16) & 0xFF);
  }
  return result;
 }
}

(8)ConstantUti.java

/**
 * 常量类
 */
public class ConstantUtil {
  public static final int TIME_MILLIS = 5 * 1000;//连接超时时间
  public static final int port = 25256;//端口号
  public static final String password = "123456885";//加密所使用的密钥
  public static final int CODE_TIMEOUT = 0;//连接超时
  public static final int CODE_SUCCESS = 1;//连接成功
  public static final int CODE_UNKNOWN_HOST = 2;//错误-未知的host
}

(9)ToolUtil.java

import android.util.Log;

import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;

/**
 * 工具类
 */
public class ToolUtil {
 /**
  * 获取ip地址
  * 如果是移动网络,会显示自己的公网IP,如果是局域网,会显示局域网IP
  * 因此本例中服务器端需要断开移动网络以得到本机局域网IP
  */
 public static String getHostIP() {

  String hostIp = null;
  try {
   Enumeration nis = NetworkInterface.getNetworkInterfaces();
   InetAddress ia;
   while (nis.hasMoreElements()) {
    NetworkInterface ni = (NetworkInterface) nis.nextElement();
    Enumeration<InetAddress> ias = ni.getInetAddresses();
    while (ias.hasMoreElements()) {
     ia = ias.nextElement();
     if (ia instanceof Inet6Address) {
      continue;// skip ipv6
     }
     String ip = ia.getHostAddress();
     if (!"127.0.0.1".equals(ip)) {
      hostIp = ia.getHostAddress();
      break;
     }
    }
   }
  } catch (SocketException e) {
   Log.i("error", "SocketException");
   e.printStackTrace();
  }
  return hostIp;

 }

 /**
  * 判断地址是否为IPV4地址
  */
 public static boolean IsIpv4(String ipv4) {
  if (ipv4 == null || ipv4.length() == 0) {
   return false;//字符串为空或者空串
  }
  String[] parts = ipv4.split("\\.");//因为java doc里已经说明, split的参数是reg, 即正则表达式, 如果用"|"分割, 则需使用"\\|"
  if (parts.length != 4) {
   return false;//分割开的数组根本就不是4个数字
  }
  for (String part : parts) {
   try {
    int n = Integer.parseInt(part);
    if (n < 0 || n > 255) {
     return false;//数字不在正确范围内
    }
   } catch (NumberFormatException e) {
    return false;//转换数字不正确
   }
  }
  return true;
 }
}

(10)ToastUtil.java

import android.content.Context;
import android.widget.Toast;

public class ToastUtil {

 private static Toast mToast = null;

 /**
  * Toast方法
  *
  * @param text 需要展示的文本
  * @param context 所需上下文
  */
 public static void showToast(Context context, String text) {
  if (text != null) {
   if (mToast == null) {
    mToast = Toast.makeText(context, text, Toast.LENGTH_SHORT);
   } else {
    mToast.setText(text);
    mToast.setDuration(Toast.LENGTH_SHORT);
   }
   mToast.show();
  }
 }

}

3.权限及声明

 <uses-permission android:name="android.permission.INTERNET" />
 <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
 <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<!--service部分-->
  <service android:name="com.test.test.LocalService"/>

代码到此为止了,功能比较简单。希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android开发中Socket通信的基本实现方法讲解

    一.Socket通信简介 Android与服务器的通信方式主要有两种,一是Http通信,一是Socket通信.两者的最大差异在于,http连接使用的是"请求-响应方式",即在请求时建立连接通道,当客户端向服务器发送请求后,服务器端才能向客户端返回数据.而Socket通信则是在双方建立起连接后就可以直接进行数据的传输,在连接时可实现信息的主动推送,而不需要每次由客户端想服务器发送请求. 那么,什么是socket?Socket又称套接字,在程序内部提供了与外界通信的端口,即端口通信.通过建

  • Android中Socket通信的实现方法概述

    本文实例简述了Android中Socket通信的实现方法,具体内容如下: 一.socket通信概述 通俗的来说套接字(socket)是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元.它是网络通信过程中端点的抽象表示,包含进行网络通信必须的五种信息:连接使用的协议,本地主机的IP地址,本地进程的协议端口,远地主机的IP地址,远地进程的协议端口. 应用层通过传输层进行数据通信时,TCP会遇到同时为多个应用程序进程提供并发服务的问题.多个TCP连接或多个应用程序进程可能需要通过同一个TCP

  • Android基于socket实现的简单C/S聊天通信功能

    本文实例讲述了Android基于socket实现的简单C/S聊天通信功能.分享给大家供大家参考,具体如下: 主要想法:在客户端上发送一条信息,在后台开辟一个线程充当服务端,收到消息就立即回馈给客户端. 第一步:创建一个继续Activity的SocketClientActity类,包为com.pku.net 编写布局文件socketclient.xml,代码如下: <?xml version="1.0" encoding="utf-8"?> <Lin

  • Android中使用socket使底层和framework通信的实现方法

    一般的native和framework的通信是通过jni,但是这一般只是framework调用native,native如果有消息要怎样通知上层 呢?android中GSP模块提供一种解决思路,但是实现有些复杂,这里介绍一种使用socket通信的方法可以使native和framework自 由通信,具体实现如下: android中使用jni对linux中的socket进行了封装.使用起来十分的方便. 由于android是基于linux的,所以linux的代码会在java之前先执行,所以一般nat

  • Android中使用socket通信实现消息推送的方法详解

    原理 最近用socket写了一个消息推送的demo,在这里和大家分享一下. 主要实现了:一台手机向另外一台手机发送消息,这两台手机可以随时自由发送文本消息进行通信,类似我们常用的QQ. 效果图: 原理:手机通过socket发送消息到服务器,服务器每接收到一条消息之后,都会把这条消息放进一个messageList里面,服务器会不停地检测messageList是否含有消息,如果有的话就会根据messageList里面item的数据,推送到相应的另一端手机上面. 下面简单画了一个图来说明这个原理: 演

  • Android Socket通信详解

    一.Socket通信简介  Android与服务器的通信方式主要有两种,一是Http通信,一是Socket通信.两者的最大差异在于,http连接使用的是"请求-响应方式",即在请求时建立连接通道,当客户端向服务器发送请求后,服务器端才能向客户端返回数据.而Socket通信则是在双方建立起连接后就可以直接进行数据的传输,在连接时可实现信息的主动推送,而不需要每次由客户端想服务器发送请求. 那么,什么是socket?Socket又称套接字,在程序内部提供了与外界通信的端口,即端口通信.通过

  • python服务器与android客户端socket通信实例

    本文实例讲述了python服务器与android客户端socket通信的方法.分享给大家供大家参考.具体实现方法如下: 首先,服务器端使用python完成,下面为python代码: 复制代码 代码如下: #server.py  import socket  def getipaddrs(hostname):#只是为了显示IP,仅仅测试一下      result = socket.getaddrinfo(hostname, None, 0, socket.SOCK_STREAM)      re

  • Android编程之客户端通过socket与服务器通信的方法

    本文实例讲述了Android编程之客户端通过socket与服务器通信的方法.分享给大家供大家参考,具体如下: 下面是一个demo,Android客户端通过socket与服务器通信. 由于Android里面可以完全使用java.io.*包和java.net.*包,那么,实际上,逻辑部分与J2SE没有区别.只是UI代码不一样. Android客户端通过socket与服务器通信分为下面5步: (1)通过IP地址和端口实例化Socket,请求连接服务器: 复制代码 代码如下: socket = new

  • Android Socket 线程连接openwrt与arduino单片机串口双向通信的实例解析

    废话不多说了,直接给大家贴代码了,具体代码如下所示: package zcd.netanything; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Socket; import android.app.Fragment; import android.content.BroadcastReceiver; import and

  • 详解Android的Socket通信、List加载更多、Spinner下拉列表

    Android与服务器的通信方式主要有两种,一是Http通信,一是Socket通信.两者的最大差异在于,http连接使用的是"请求-响应方式",即在请求时建立连接通道,当客户端向服务器发送请求后,服务器端才能向客户端返回数据.而Socket通信则是在双方建立起连接后就可以直接进行数据的传输,在连接时可实现信息的主动推送,而不需要每次由客户端想服务器发送请求. 那么,什么是socket?Socket又称套接字,在程序内部提供了与外界通信的端口,即端口通信.通过建立socket连接,可为通

随机推荐