PC客户端与Android服务端的Socket同步通信(USB)

时间 : 15-11-09 栏目 : Android, 移动开发 作者 : noway 评论 : 0 点击 : 350 次

PC客户端与Android服务端的Socket同步通信(USB) 收藏

需求:

 

  1. 一个android端的service后台运行的程序,作为socket的服务器端;用于接收Pc client端发来的命令,来处理数据后,把结果发给PC client

 

2.PC端程序,作为socket的客户端,用于给android手机端发操作命令

 

难点分析:

 

  1. 手机一定要有adb模式,即插上USB线时马上提示的对话框选adb。好多对手机的操作都可以用adb直接作。

 

不过,我发现LG GW880就没有,要去下载个

 

2.android默认手机端的IP为“127.0.0.1”

 

  1. 要想联通PC与android手机的sokcet,一定要用adb forward 来作下端口转发才能连上socket.

 

view plaincopy to clipboardprint?

Runtime.getRuntime().exec("adb forward tcp:12580 tcp:10086");

Thread.sleep(3000);

Runtime.getRuntime().exec("adb forward tcp:12580 tcp:10086");

Thread.sleep(3000);

 

4.android端的service程序Install到手机上容易,但是还要有方法来从PC的client端来启动手机上的service ,这个办法可以通过PC端adb命令来发一个Broastcast ,手机端再写个接收BroastcastReceive来接收这个Broastcast,在这个BroastcastReceive来启动service

 

 

pc端命令:

 

view plaincopy to clipboardprint?

Runtime.getRuntime().exec(

"adb shell am broadcast -a NotifyServiceStart");

Runtime.getRuntime().exec(

"adb shell am broadcast -a NotifyServiceStart");

 

android端的代码:ServiceBroadcastReceiver.java

 

view plaincopy to clipboardprint?

package com.otheri.service;

import android.content.BroadcastReceiver;

import android.content.Context;

import android.content.Intent;

import android.util.Log;

public class ServiceBroadcastReceiver extends BroadcastReceiver {

private static String START_ACTION = "NotifyServiceStart";

private static String STOP_ACTION = "NotifyServiceStop";

@Override

public void onReceive(Context context, Intent intent) {

Log.d(androidService.TAG, Thread.currentThread().getName() + "---->"

+ "ServiceBroadcastReceiver onReceive");

String action = intent.getAction();

if (START_ACTION.equalsIgnoreCase(action)) {

context.startService(new Intent(context, androidService.class));

Log.d(androidService.TAG, Thread.currentThread().getName() + "---->"

+ "ServiceBroadcastReceiver onReceive start end");

} else if (STOP_ACTION.equalsIgnoreCase(action)) {

context.stopService(new Intent(context, androidService.class));

Log.d(androidService.TAG, Thread.currentThread().getName() + "---->"

+ "ServiceBroadcastReceiver onReceive stop end");

}

}

}

package com.otheri.service;

 

import android.content.BroadcastReceiver;

import android.content.Context;

import android.content.Intent;

import android.util.Log;

 

public class ServiceBroadcastReceiver extends BroadcastReceiver {

private static String START_ACTION = "NotifyServiceStart";

private static String STOP_ACTION = "NotifyServiceStop";

 

@Override

public void onReceive(Context context, Intent intent) {

Log.d(androidService.TAG, Thread.currentThread().getName() + "---->"

+ "ServiceBroadcastReceiver onReceive");

 

String action = intent.getAction();

if (START_ACTION.equalsIgnoreCase(action)) {

context.startService(new Intent(context, androidService.class));

 

Log.d(androidService.TAG, Thread.currentThread().getName() + "---->"

+ "ServiceBroadcastReceiver onReceive start end");

} else if (STOP_ACTION.equalsIgnoreCase(action)) {

context.stopService(new Intent(context, androidService.class));

Log.d(androidService.TAG, Thread.currentThread().getName() + "---->"

+ "ServiceBroadcastReceiver onReceive stop end");

}

}

 

}

 

  1. 由于是USB连接,所以socket就可以设计为一但连接就一直联通,即在new socket和开完out,in流后,就用个while(true){}来循环PC端和android端的读和写

 

android的代码:

 

view plaincopy to clipboardprint?

public void run() {

Log.d(androidService.TAG, Thread.currentThread().getName() + "---->"

+ "a client has connected to server!");

BufferedOutputStream out;

BufferedInputStream in;

try {

/* PC端发来的数据msg */

String currCMD = "";

out = new BufferedOutputStream(client.getOutputStream());

in = new BufferedInputStream(client.getInputStream());

// testSocket();// 测试socket方法

androidService.ioThreadFlag = true;

while (androidService.ioThreadFlag) {

try {

if (!client.isConnected()) {

break;

}

/* 接收PC发来的数据 */

Log.v(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "will read......");

/* 读操作命令 */

currCMD = readCMDFromSocket(in);

Log.v(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "**currCMD ==== " + currCMD);

/* 根据命令分别处理数据 */

if (currCMD.equals("1")) {

out.write("OK".getBytes());

out.flush();

} else if (currCMD.equals("2")) {

out.write("OK".getBytes());

out.flush();

} else if (currCMD.equals("3")) {

out.write("OK".getBytes());

out.flush();

} else if (currCMD.equals("4")) {

/* 准备接收文件数据 */

try {

out.write("service receive OK".getBytes());

out.flush();

} catch (IOException e) {

e.printStackTrace();

}

/* 接收文件数据,4字节文件长度,4字节文件格式,其后是文件数据 */

byte[] filelength = new byte[4];

byte[] fileformat = new byte[4];

byte[] filebytes = null;

/* 从socket流中读取完整文件数据 */

filebytes = receiveFileFromSocket(in, out, filelength,

fileformat);

// Log.v(Service139.TAG, "receive data =" + new

// String(filebytes));

try {

/* 生成文件 */

File file = FileHelper.newFile("R0013340.JPG");

FileHelper.writeFile(file, filebytes, 0,

filebytes.length);

} catch (IOException e) {

e.printStackTrace();

}

} else if (currCMD.equals("exit")) {

}

} catch (Exception e) {

// try {

// out.write("error".getBytes("utf-8"));

// out.flush();

// } catch (IOException e1) {

// e1.printStackTrace();

// }

Log.e(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "read write error111111");

}

}

out.close();

in.close();

} catch (Exception e) {

Log.e(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "read write error222222");

e.printStackTrace();

} finally {

try {

if (client != null) {

Log.v(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "client.close()");

client.close();

}

} catch (IOException e) {

Log.e(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "read write error333333");

e.printStackTrace();

}

}

public void run() {

Log.d(androidService.TAG, Thread.currentThread().getName() + "---->"

+ "a client has connected to server!");

BufferedOutputStream out;

BufferedInputStream in;

try {

/* PC端发来的数据msg */

String currCMD = "";

out = new BufferedOutputStream(client.getOutputStream());

in = new BufferedInputStream(client.getInputStream());

// testSocket();// 测试socket方法

androidService.ioThreadFlag = true;

while (androidService.ioThreadFlag) {

try {

if (!client.isConnected()) {

break;

}

 

/* 接收PC发来的数据 */

Log.v(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "will read......");

/* 读操作命令 */

currCMD = readCMDFromSocket(in);

Log.v(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "**currCMD ==== " + currCMD);

 

/* 根据命令分别处理数据 */

if (currCMD.equals("1")) {

out.write("OK".getBytes());

out.flush();

} else if (currCMD.equals("2")) {

out.write("OK".getBytes());

out.flush();

} else if (currCMD.equals("3")) {

out.write("OK".getBytes());

out.flush();

} else if (currCMD.equals("4")) {

/* 准备接收文件数据 */

try {

out.write("service receive OK".getBytes());

out.flush();

} catch (IOException e) {

e.printStackTrace();

}

 

/* 接收文件数据,4字节文件长度,4字节文件格式,其后是文件数据 */

byte[] filelength = new byte[4];

byte[] fileformat = new byte[4];

byte[] filebytes = null;

 

/* 从socket流中读取完整文件数据 */

filebytes = receiveFileFromSocket(in, out, filelength,

fileformat);

 

// Log.v(Service139.TAG, "receive data =" + new

// String(filebytes));

try {

/* 生成文件 */

File file = FileHelper.newFile("R0013340.JPG");

FileHelper.writeFile(file, filebytes, 0,

filebytes.length);

} catch (IOException e) {

e.printStackTrace();

}

} else if (currCMD.equals("exit")) {

 

}

} catch (Exception e) {

// try {

// out.write("error".getBytes("utf-8"));

// out.flush();

// } catch (IOException e1) {

// e1.printStackTrace();

// }

Log.e(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "read write error111111");

}

}

out.close();

in.close();

} catch (Exception e) {

Log.e(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "read write error222222");

e.printStackTrace();

} finally {

try {

if (client != null) {

Log.v(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "client.close()");

client.close();

}

} catch (IOException e) {

Log.e(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "read write error333333");

e.printStackTrace();

}

}

 

  1. 如果是在PC端和android端的读写操作来while(true){}循环,这样socket流的结尾不好判断,不能用“-1”来判断,因为“-1”是只有在socket关闭时才作为判断结尾。

 

7.socket在out.write(bytes);时,要是数据太大时,超过socket的缓存,socket自动分包发送,所以对方就一定要用循环来多次读。最好的办法就是服务器和客户端协议好,比如发文件时,先写过来一个要发送的文件的大小,然后再发送文件;对方用这个大小,来循环读取数据。

 

android端接收数据的代码:

 

view plaincopy to clipboardprint?

/**

* 功能:从socket流中读取完整文件数据

*

* InputStream in:socket输入流

*

* byte[] filelength: 流的前4个字节存储要转送的文件的字节数

*

* byte[] fileformat:流的前5-8字节存储要转送的文件的格式(如.apk)

*

* */

public static byte[] receiveFileFromSocket(InputStream in,

OutputStream out, byte[] filelength, byte[] fileformat) {

byte[] filebytes = null;// 文件数据

try {

int filelen = MyUtil.bytesToInt(filelength);// 文件长度从4字节byte[]转成Int

String strtmp = "read file length ok:" + filelen;

out.write(strtmp.getBytes("utf-8"));

out.flush();

filebytes = new byte[filelen];

int pos = 0;

int rcvLen = 0;

while ((rcvLen = in.read(filebytes, pos, filelen - pos)) > 0) {

pos += rcvLen;

}

Log.v(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "read file OK:file size=" + filebytes.length);

out.write("read file ok".getBytes("utf-8"));

out.flush();

} catch (Exception e) {

Log.v(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "receiveFileFromSocket error");

e.printStackTrace();

}

return filebytes;

}

/**

* 功能:从socket流中读取完整文件数据

*

* InputStream in:socket输入流

*

* byte[] filelength: 流的前4个字节存储要转送的文件的字节数

*

* byte[] fileformat:流的前5-8字节存储要转送的文件的格式(如.apk)

*

* */

public static byte[] receiveFileFromSocket(InputStream in,

OutputStream out, byte[] filelength, byte[] fileformat) {

byte[] filebytes = null;// 文件数据

try {

int filelen = MyUtil.bytesToInt(filelength);// 文件长度从4字节byte[]转成Int

String strtmp = "read file length ok:" + filelen;

out.write(strtmp.getBytes("utf-8"));

out.flush();

 

filebytes = new byte[filelen];

int pos = 0;

int rcvLen = 0;

while ((rcvLen = in.read(filebytes, pos, filelen - pos)) > 0) {

pos += rcvLen;

}

Log.v(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "read file OK:file size=" + filebytes.length);

out.write("read file ok".getBytes("utf-8"));

out.flush();

} catch (Exception e) {

Log.v(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "receiveFileFromSocket error");

e.printStackTrace();

}

return filebytes;

}

 

8.socket的最重要的机制就是读写采用的是阻塞的方式,如果客户端作为命令发起者,服务器端作为接收者的话,只有当客户端client用out.writer()写到输出流里后,即流中有数据service的read才会执行,不然就会一直停在read()那里等数据。

 

  1. 还要让服务器端可以同时连接多个client,即服务器端用new thread()来作数据读取操作。

 

源码:

 

客户端(pc端):

 

 

 

testPcClient.java

 

view plaincopy to clipboardprint?

import java.io.BufferedInputStream;

import java.io.BufferedOutputStream;

import java.io.BufferedReader;

import java.io.ByteArrayOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.net.InetAddress;

import java.net.Socket;

import java.net.UnknownHostException;

public class testPcClient {

/**

* @param args

* @throws InterruptedException

*/

public static void main(String[] args) throws InterruptedException {

try {

Runtime.getRuntime().exec(

"adb shell am broadcast -a NotifyServiceStop");

Thread.sleep(3000);

Runtime.getRuntime().exec("adb forward tcp:12580 tcp:10086");

Thread.sleep(3000);

Runtime.getRuntime().exec(

"adb shell am broadcast -a NotifyServiceStart");

Thread.sleep(3000);

} catch (IOException e3) {

e3.printStackTrace();

}

Socket socket = null;

try {

InetAddress serverAddr = null;

serverAddr = InetAddress.getByName("127.0.0.1");

System.out.println("TCP 1111" + "C: Connecting...");

socket = new Socket(serverAddr, 12580);

String str = "hi,wufenglong";

System.out.println("TCP 221122" + "C:RECEIVE");

BufferedOutputStream out = new BufferedOutputStream(socket

.getOutputStream());

BufferedInputStream in = new BufferedInputStream(socket

.getInputStream());

BufferedReader br = new BufferedReader(new InputStreamReader(

System.in));

boolean flag = true;

while (flag) {

System.out.print("请输入1~6的数字,退出输入exit:");

String strWord = br.readLine();// 从控制台输入1~6

if (strWord.equals("1")) {

out.write("1".getBytes());

out.flush();

System.out.println("1 finish sending the data");

String strFormsocket = readFromSocket(in);

System.out.println("the data sent by server is:\r\n"

+ strFormsocket);

System.out

.println("=============================================");

} else if (strWord.equals("2")) {

out.write("2".getBytes());

out.flush();

System.out.println("2 finish sending the data");

String strFormsocket = readFromSocket(in);

System.out.println("the data sent by server is:\r\n"

+ strFormsocket);

System.out

.println("=============================================");

} else if (strWord.equals("3")) {

out.write("3".getBytes());

out.flush();

System.out.println("3 finish sending the data");

String strFormsocket = readFromSocket(in);

System.out.println("the data sent by server is:\r\n"

+ strFormsocket);

System.out

.println("=============================================");

} else if (strWord.equals("4")) {

/* 发送命令 */

out.write("4".getBytes());

out.flush();

System.out.println("send file finish sending the CMD:");

/* 服务器反馈:准备接收 */

String strFormsocket = readFromSocket(in);

System.out

.println("service ready receice data:UPDATE_CONTACTS:"

+ strFormsocket);

byte[] filebytes = FileHelper.readFile("R0013340.JPG");

System.out.println("file size=" + filebytes.length);

/* 将整数转成4字节byte数组 */

byte[] filelength = new byte[4];

filelength = tools.intToByte(filebytes.length);

/* 将.apk字符串转成4字节byte数组 */

byte[] fileformat = null;

fileformat = ".apk".getBytes();

System.out

.println("fileformat length=" + fileformat.length);

/* 字节流中前4字节为文件长度,4字节文件格式,以后是文件流 */

/* 注意如果write里的byte[]超过socket的缓存,系统自动分包写过去,所以对方要循环写完 */

out.write(filelength);

out.flush();

String strok1 = readFromSocket(in);

System.out.println("service receive filelength :" + strok1);

// out.write(fileformat);

// out.flush();

// String strok2 = readFromSocket(in);

// System.out.println("service receive fileformat :" +

// strok2);

System.out.println("write data to android");

out.write(filebytes);

out.flush();

System.out.println("*********");

/* 服务器反馈:接收成功 */

String strread = readFromSocket(in);

System.out.println(" send data success:" + strread);

System.out

.println("=============================================");

} else if (strWord.equalsIgnoreCase("EXIT")) {

out.write("EXIT".getBytes());

out.flush();

System.out.println("EXIT finish sending the data");

String strFormsocket = readFromSocket(in);

System.out.println("the data sent by server is:\r\n"

+ strFormsocket);

flag = false;

System.out

.println("=============================================");

}

}

} catch (UnknownHostException e1) {

System.out.println("TCP 331133" + "ERROR:" + e1.toString());

} catch (Exception e2) {

System.out.println("TCP 441144" + "ERROR:" + e2.toString());

} finally {

try {

if (socket != null) {

socket.close();

System.out.println("socket.close()");

}

} catch (IOException e) {

System.out.println("TCP 5555" + "ERROR:" + e.toString());

}

}

}

/* 从InputStream流中读数据 */

public static String readFromSocket(InputStream in) {

int MAX_BUFFER_BYTES = 4000;

String msg = "";

byte[] tempbuffer = new byte[MAX_BUFFER_BYTES];

try {

int numReadedBytes = in.read(tempbuffer, 0, tempbuffer.length);

msg = new String(tempbuffer, 0, numReadedBytes, "utf-8");

tempbuffer = null;

} catch (Exception e) {

e.printStackTrace();

}

// Log.v(Service139.TAG, "msg=" + msg);

return msg;

}

}

import java.io.BufferedInputStream;

import java.io.BufferedOutputStream;

import java.io.BufferedReader;

import java.io.ByteArrayOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.net.InetAddress;

import java.net.Socket;

import java.net.UnknownHostException;

 

public class testPcClient {

 

/**

* @param args

* @throws InterruptedException

*/

public static void main(String[] args) throws InterruptedException {

try {

Runtime.getRuntime().exec(

"adb shell am broadcast -a NotifyServiceStop");

Thread.sleep(3000);

Runtime.getRuntime().exec("adb forward tcp:12580 tcp:10086");

Thread.sleep(3000);

Runtime.getRuntime().exec(

"adb shell am broadcast -a NotifyServiceStart");

Thread.sleep(3000);

} catch (IOException e3) {

e3.printStackTrace();

}

 

Socket socket = null;

try {

InetAddress serverAddr = null;

serverAddr = InetAddress.getByName("127.0.0.1");

System.out.println("TCP 1111" + "C: Connecting...");

socket = new Socket(serverAddr, 12580);

String str = "hi,wufenglong";

System.out.println("TCP 221122" + "C:RECEIVE");

BufferedOutputStream out = new BufferedOutputStream(socket

.getOutputStream());

BufferedInputStream in = new BufferedInputStream(socket

.getInputStream());

BufferedReader br = new BufferedReader(new InputStreamReader(

System.in));

boolean flag = true;

while (flag) {

System.out.print("请输入1~6的数字,退出输入exit:");

String strWord = br.readLine();// 从控制台输入1~6

if (strWord.equals("1")) {

out.write("1".getBytes());

out.flush();

System.out.println("1 finish sending the data");

String strFormsocket = readFromSocket(in);

System.out.println("the data sent by server is:\r\n"

+ strFormsocket);

System.out

.println("=============================================");

} else if (strWord.equals("2")) {

out.write("2".getBytes());

out.flush();

System.out.println("2 finish sending the data");

String strFormsocket = readFromSocket(in);

System.out.println("the data sent by server is:\r\n"

+ strFormsocket);

System.out

.println("=============================================");

} else if (strWord.equals("3")) {

out.write("3".getBytes());

out.flush();

System.out.println("3 finish sending the data");

String strFormsocket = readFromSocket(in);

System.out.println("the data sent by server is:\r\n"

+ strFormsocket);

System.out

.println("=============================================");

} else if (strWord.equals("4")) {

/* 发送命令 */

out.write("4".getBytes());

out.flush();

System.out.println("send file finish sending the CMD:");

/* 服务器反馈:准备接收 */

String strFormsocket = readFromSocket(in);

System.out

.println("service ready receice data:UPDATE_CONTACTS:"

+ strFormsocket);

byte[] filebytes = FileHelper.readFile("R0013340.JPG");

System.out.println("file size=" + filebytes.length);

/* 将整数转成4字节byte数组 */

byte[] filelength = new byte[4];

filelength = tools.intToByte(filebytes.length);

/* 将.apk字符串转成4字节byte数组 */

byte[] fileformat = null;

fileformat = ".apk".getBytes();

System.out

.println("fileformat length=" + fileformat.length);

/* 字节流中前4字节为文件长度,4字节文件格式,以后是文件流 */

/* 注意如果write里的byte[]超过socket的缓存,系统自动分包写过去,所以对方要循环写完 */

out.write(filelength);

out.flush();

String strok1 = readFromSocket(in);

System.out.println("service receive filelength :" + strok1);

// out.write(fileformat);

// out.flush();

// String strok2 = readFromSocket(in);

// System.out.println("service receive fileformat :" +

// strok2);

System.out.println("write data to android");

out.write(filebytes);

out.flush();

System.out.println("*********");

 

/* 服务器反馈:接收成功 */

String strread = readFromSocket(in);

System.out.println(" send data success:" + strread);

System.out

.println("=============================================");

} else if (strWord.equalsIgnoreCase("EXIT")) {

out.write("EXIT".getBytes());

out.flush();

System.out.println("EXIT finish sending the data");

String strFormsocket = readFromSocket(in);

System.out.println("the data sent by server is:\r\n"

+ strFormsocket);

flag = false;

System.out

.println("=============================================");

}

}

 

} catch (UnknownHostException e1) {

System.out.println("TCP 331133" + "ERROR:" + e1.toString());

} catch (Exception e2) {

System.out.println("TCP 441144" + "ERROR:" + e2.toString());

} finally {

try {

if (socket != null) {

socket.close();

System.out.println("socket.close()");

}

} catch (IOException e) {

System.out.println("TCP 5555" + "ERROR:" + e.toString());

}

}

}

 

/* 从InputStream流中读数据 */

public static String readFromSocket(InputStream in) {

int MAX_BUFFER_BYTES = 4000;

String msg = "";

byte[] tempbuffer = new byte[MAX_BUFFER_BYTES];

try {

int numReadedBytes = in.read(tempbuffer, 0, tempbuffer.length);

msg = new String(tempbuffer, 0, numReadedBytes, "utf-8");

 

tempbuffer = null;

} catch (Exception e) {

e.printStackTrace();

}

// Log.v(Service139.TAG, "msg=" + msg);

return msg;

}

}

 

android服务器端:

 

 

 

主类androidService.java

 

view plaincopy to clipboardprint?

package com.otheri.service;

import java.io.File;

import java.io.IOException;

import java.net.ServerSocket;

import java.net.Socket;

import android.app.Service;

import android.content.BroadcastReceiver;

import android.content.Context;

import android.content.Intent;

import android.content.IntentFilter;

import android.os.IBinder;

import android.util.Log;

/**

* 设置:android手机

*

*

* */

public class androidService extends Service {

public static final String TAG = "TAG";

public static Boolean mainThreadFlag = true;

public static Boolean ioThreadFlag = true;

ServerSocket serverSocket = null;

final int SERVER_PORT = 10086;

File testFile;

private sysBroadcastReceiver sysBR;

@Override

public void onCreate() {

super.onCreate();

Log.v(TAG, Thread.currentThread().getName() + "---->" + " onCreate");

/* 创建内部类sysBroadcastReceiver 并注册registerReceiver */

sysRegisterReceiver();

new Thread() {

public void run() {

doListen();

};

}.start();

}

private void doListen() {

Log.d(TAG, Thread.currentThread().getName() + "---->"

+ " doListen() START");

serverSocket = null;

try {

Log.d(TAG, Thread.currentThread().getName() + "---->"

+ " doListen() new serverSocket");

serverSocket = new ServerSocket(SERVER_PORT);

boolean mainThreadFlag = true;

while (mainThreadFlag) {

Log.d(TAG, Thread.currentThread().getName() + "---->"

+ " doListen() listen");

Socket client = serverSocket.accept();

new Thread(new ThreadReadWriterIOSocket(this, client)).start();

}

} catch (IOException e1) {

Log.v(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "new serverSocket error");

e1.printStackTrace();

}

}

/* 创建内部类sysBroadcastReceiver 并注册registerReceiver */

private void sysRegisterReceiver() {

Log.v(TAG, Thread.currentThread().getName() + "---->"

+ "sysRegisterReceiver");

sysBR = new sysBroadcastReceiver();

/* 注册BroadcastReceiver */

IntentFilter filter1 = new IntentFilter();

/* 新的应用程序被安装到了设备上的广播 */

filter1.addAction("android.intent.action.PACKAGE_ADDED");

filter1.addDataScheme("package");

filter1.addAction("android.intent.action.PACKAGE_REMOVED");

filter1.addDataScheme("package");

registerReceiver(sysBR, filter1);

}

/* 内部类:BroadcastReceiver 用于接收系统事件 */

private class sysBroadcastReceiver extends BroadcastReceiver {

@Override

public void onReceive(Context context, Intent intent) {

String action = intent.getAction();

if (action.equalsIgnoreCase("android.intent.action.PACKAGE_ADDED")) {

// ReadInstalledAPP();

} else if (action

.equalsIgnoreCase("android.intent.action.PACKAGE_REMOVED")) {

// ReadInstalledAPP();

}

Log.v(TAG, Thread.currentThread().getName() + "---->"

+ "sysBroadcastReceiver onReceive");

}

}

@Override

public void onDestroy() {

super.onDestroy();

// 关闭线程

mainThreadFlag = false;

ioThreadFlag = false;

// 关闭服务器

try {

Log.v(TAG, Thread.currentThread().getName() + "---->"

+ "serverSocket.close()");

serverSocket.close();

} catch (IOException e) {

e.printStackTrace();

}

Log.v(TAG, Thread.currentThread().getName() + "---->"

+ "**************** onDestroy****************");

}

@Override

public void onStart(Intent intent, int startId) {

Log.d(TAG, Thread.currentThread().getName() + "---->" + " onStart()");

super.onStart(intent, startId);

}

@Override

public IBinder onBind(Intent arg0) {

Log.d(TAG, " onBind");

return null;

}

}

package com.otheri.service;

 

import java.io.File;

import java.io.IOException;

import java.net.ServerSocket;

import java.net.Socket;

 

import android.app.Service;

import android.content.BroadcastReceiver;

import android.content.Context;

import android.content.Intent;

import android.content.IntentFilter;

import android.os.IBinder;

import android.util.Log;

 

/**

* 设置:android手机

*

*

* */

public class androidService extends Service {

public static final String TAG = "TAG";

public static Boolean mainThreadFlag = true;

public static Boolean ioThreadFlag = true;

ServerSocket serverSocket = null;

final int SERVER_PORT = 10086;

File testFile;

private sysBroadcastReceiver sysBR;

 

@Override

public void onCreate() {

super.onCreate();

Log.v(TAG, Thread.currentThread().getName() + "---->" + " onCreate");

/* 创建内部类sysBroadcastReceiver 并注册registerReceiver */

sysRegisterReceiver();

new Thread() {

public void run() {

doListen();

};

}.start();

}

 

private void doListen() {

Log.d(TAG, Thread.currentThread().getName() + "---->"

+ " doListen() START");

serverSocket = null;

try {

Log.d(TAG, Thread.currentThread().getName() + "---->"

+ " doListen() new serverSocket");

serverSocket = new ServerSocket(SERVER_PORT);

 

boolean mainThreadFlag = true;

while (mainThreadFlag) {

Log.d(TAG, Thread.currentThread().getName() + "---->"

+ " doListen() listen");

 

Socket client = serverSocket.accept();

 

new Thread(new ThreadReadWriterIOSocket(this, client)).start();

}

} catch (IOException e1) {

Log.v(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "new serverSocket error");

e1.printStackTrace();

}

}

 

/* 创建内部类sysBroadcastReceiver 并注册registerReceiver */

private void sysRegisterReceiver() {

Log.v(TAG, Thread.currentThread().getName() + "---->"

+ "sysRegisterReceiver");

sysBR = new sysBroadcastReceiver();

/* 注册BroadcastReceiver */

IntentFilter filter1 = new IntentFilter();

/* 新的应用程序被安装到了设备上的广播 */

filter1.addAction("android.intent.action.PACKAGE_ADDED");

filter1.addDataScheme("package");

filter1.addAction("android.intent.action.PACKAGE_REMOVED");

filter1.addDataScheme("package");

registerReceiver(sysBR, filter1);

}

 

/* 内部类:BroadcastReceiver 用于接收系统事件 */

private class sysBroadcastReceiver extends BroadcastReceiver {

 

@Override

public void onReceive(Context context, Intent intent) {

String action = intent.getAction();

if (action.equalsIgnoreCase("android.intent.action.PACKAGE_ADDED")) {

// ReadInstalledAPP();

} else if (action

.equalsIgnoreCase("android.intent.action.PACKAGE_REMOVED")) {

// ReadInstalledAPP();

}

Log.v(TAG, Thread.currentThread().getName() + "---->"

+ "sysBroadcastReceiver onReceive");

}

}

 

@Override

public void onDestroy() {

super.onDestroy();

 

// 关闭线程

mainThreadFlag = false;

ioThreadFlag = false;

// 关闭服务器

try {

Log.v(TAG, Thread.currentThread().getName() + "---->"

+ "serverSocket.close()");

serverSocket.close();

} catch (IOException e) {

e.printStackTrace();

}

Log.v(TAG, Thread.currentThread().getName() + "---->"

+ "**************** onDestroy****************");

}

 

@Override

public void onStart(Intent intent, int startId) {

Log.d(TAG, Thread.currentThread().getName() + "---->" + " onStart()");

super.onStart(intent, startId);

 

}

 

@Override

public IBinder onBind(Intent arg0) {

Log.d(TAG, " onBind");

return null;

}

 

}

 

用于接收PC发来的Broastcast并启动主类service的ServiceBroadcastReceiver.java

 

view plaincopy to clipboardprint?

package com.otheri.service;

import android.content.BroadcastReceiver;

import android.content.Context;

import android.content.Intent;

import android.util.Log;

public class ServiceBroadcastReceiver extends BroadcastReceiver {

private static String START_ACTION = "NotifyServiceStart";

private static String STOP_ACTION = "NotifyServiceStop";

@Override

public void onReceive(Context context, Intent intent) {

Log.d(androidService.TAG, Thread.currentThread().getName() + "---->"

+ "ServiceBroadcastReceiver onReceive");

String action = intent.getAction();

if (START_ACTION.equalsIgnoreCase(action)) {

context.startService(new Intent(context, androidService.class));

Log.d(androidService.TAG, Thread.currentThread().getName() + "---->"

+ "ServiceBroadcastReceiver onReceive start end");

} else if (STOP_ACTION.equalsIgnoreCase(action)) {

context.stopService(new Intent(context, androidService.class));

Log.d(androidService.TAG, Thread.currentThread().getName() + "---->"

+ "ServiceBroadcastReceiver onReceive stop end");

}

}

}

package com.otheri.service;

 

import android.content.BroadcastReceiver;

import android.content.Context;

import android.content.Intent;

import android.util.Log;

 

public class ServiceBroadcastReceiver extends BroadcastReceiver {

private static String START_ACTION = "NotifyServiceStart";

private static String STOP_ACTION = "NotifyServiceStop";

 

@Override

public void onReceive(Context context, Intent intent) {

Log.d(androidService.TAG, Thread.currentThread().getName() + "---->"

+ "ServiceBroadcastReceiver onReceive");

 

String action = intent.getAction();

if (START_ACTION.equalsIgnoreCase(action)) {

context.startService(new Intent(context, androidService.class));

 

Log.d(androidService.TAG, Thread.currentThread().getName() + "---->"

+ "ServiceBroadcastReceiver onReceive start end");

} else if (STOP_ACTION.equalsIgnoreCase(action)) {

context.stopService(new Intent(context, androidService.class));

Log.d(androidService.TAG, Thread.currentThread().getName() + "---->"

+ "ServiceBroadcastReceiver onReceive stop end");

}

}

 

}

 

用于新socket连接的读写线程类ThreadReadWriterIOSocket.java

 

view plaincopy to clipboardprint?

package com.otheri.service;

import java.io.BufferedInputStream;

import java.io.BufferedOutputStream;

import java.io.ByteArrayOutputStream;

import java.io.File;

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

import java.net.Socket;

import android.content.Context;

import android.util.Log;

import com.otheri.util.FileHelper;

import com.otheri.util.MyUtil;

/**

* 功能:用于socket的交互

*

* @author wufenglong

*

*/

public class ThreadReadWriterIOSocket implements Runnable {

private Socket client;

private Context context;

ThreadReadWriterIOSocket(Context context, Socket client) {

this.client = client;

this.context = context;

}

@Override

public void run() {

Log.d(androidService.TAG, Thread.currentThread().getName() + "---->"

+ "a client has connected to server!");

BufferedOutputStream out;

BufferedInputStream in;

try {

/* PC端发来的数据msg */

String currCMD = "";

out = new BufferedOutputStream(client.getOutputStream());

in = new BufferedInputStream(client.getInputStream());

// testSocket();// 测试socket方法

androidService.ioThreadFlag = true;

while (androidService.ioThreadFlag) {

try {

if (!client.isConnected()) {

break;

}

/* 接收PC发来的数据 */

Log.v(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "will read......");

/* 读操作命令 */

currCMD = readCMDFromSocket(in);

Log.v(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "**currCMD ==== " + currCMD);

/* 根据命令分别处理数据 */

if (currCMD.equals("1")) {

out.write("OK".getBytes());

out.flush();

} else if (currCMD.equals("2")) {

out.write("OK".getBytes());

out.flush();

} else if (currCMD.equals("3")) {

out.write("OK".getBytes());

out.flush();

} else if (currCMD.equals("4")) {

/* 准备接收文件数据 */

try {

out.write("service receive OK".getBytes());

out.flush();

} catch (IOException e) {

e.printStackTrace();

}

/* 接收文件数据,4字节文件长度,4字节文件格式,其后是文件数据 */

byte[] filelength = new byte[4];

byte[] fileformat = new byte[4];

byte[] filebytes = null;

/* 从socket流中读取完整文件数据 */

filebytes = receiveFileFromSocket(in, out, filelength,

fileformat);

// Log.v(Service139.TAG, "receive data =" + new

// String(filebytes));

try {

/* 生成文件 */

File file = FileHelper.newFile("R0013340.JPG");

FileHelper.writeFile(file, filebytes, 0,

filebytes.length);

} catch (IOException e) {

e.printStackTrace();

}

} else if (currCMD.equals("exit")) {

}

} catch (Exception e) {

// try {

// out.write("error".getBytes("utf-8"));

// out.flush();

// } catch (IOException e1) {

// e1.printStackTrace();

// }

Log.e(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "read write error111111");

}

}

out.close();

in.close();

} catch (Exception e) {

Log.e(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "read write error222222");

e.printStackTrace();

} finally {

try {

if (client != null) {

Log.v(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "client.close()");

client.close();

}

} catch (IOException e) {

Log.e(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "read write error333333");

e.printStackTrace();

}

}

}

/**

* 功能:从socket流中读取完整文件数据

*

* InputStream in:socket输入流

*

* byte[] filelength: 流的前4个字节存储要转送的文件的字节数

*

* byte[] fileformat:流的前5-8字节存储要转送的文件的格式(如.apk)

*

* */

public static byte[] receiveFileFromSocket(InputStream in,

OutputStream out, byte[] filelength, byte[] fileformat) {

byte[] filebytes = null;// 文件数据

try {

in.read(filelength);// 读文件长度

int filelen = MyUtil.bytesToInt(filelength);// 文件长度从4字节byte[]转成Int

String strtmp = "read file length ok:" + filelen;

out.write(strtmp.getBytes("utf-8"));

out.flush();

filebytes = new byte[filelen];

int pos = 0;

int rcvLen = 0;

while ((rcvLen = in.read(filebytes, pos, filelen - pos)) > 0) {

pos += rcvLen;

}

Log.v(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "read file OK:file size=" + filebytes.length);

out.write("read file ok".getBytes("utf-8"));

out.flush();

} catch (Exception e) {

Log.v(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "receiveFileFromSocket error");

e.printStackTrace();

}

return filebytes;

}

/* 读取命令 */

public static String readCMDFromSocket(InputStream in) {

int MAX_BUFFER_BYTES = 2048;

String msg = "";

byte[] tempbuffer = new byte[MAX_BUFFER_BYTES];

try {

int numReadedBytes = in.read(tempbuffer, 0, tempbuffer.length);

msg = new String(tempbuffer, 0, numReadedBytes, "utf-8");

tempbuffer = null;

} catch (Exception e) {

Log.v(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "readFromSocket error");

e.printStackTrace();

}

// Log.v(Service139.TAG, "msg=" + msg);

return msg;

}

}

package com.otheri.service;

 

import java.io.BufferedInputStream;

import java.io.BufferedOutputStream;

import java.io.ByteArrayOutputStream;

import java.io.File;

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

import java.net.Socket;

 

import android.content.Context;

import android.util.Log;

 

import com.otheri.util.FileHelper;

import com.otheri.util.MyUtil;

 

/**

* 功能:用于socket的交互

*

* @author wufenglong

*

*/

public class ThreadReadWriterIOSocket implements Runnable {

private Socket client;

private Context context;

 

ThreadReadWriterIOSocket(Context context, Socket client) {

 

this.client = client;

this.context = context;

}

 

@Override

public void run() {

Log.d(androidService.TAG, Thread.currentThread().getName() + "---->"

+ "a client has connected to server!");

BufferedOutputStream out;

BufferedInputStream in;

try {

/* PC端发来的数据msg */

String currCMD = "";

out = new BufferedOutputStream(client.getOutputStream());

in = new BufferedInputStream(client.getInputStream());

// testSocket();// 测试socket方法

androidService.ioThreadFlag = true;

while (androidService.ioThreadFlag) {

try {

if (!client.isConnected()) {

break;

}

 

/* 接收PC发来的数据 */

Log.v(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "will read......");

/* 读操作命令 */

currCMD = readCMDFromSocket(in);

Log.v(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "**currCMD ==== " + currCMD);

 

/* 根据命令分别处理数据 */

if (currCMD.equals("1")) {

out.write("OK".getBytes());

out.flush();

} else if (currCMD.equals("2")) {

out.write("OK".getBytes());

out.flush();

} else if (currCMD.equals("3")) {

out.write("OK".getBytes());

out.flush();

} else if (currCMD.equals("4")) {

/* 准备接收文件数据 */

try {

out.write("service receive OK".getBytes());

out.flush();

} catch (IOException e) {

e.printStackTrace();

}

 

/* 接收文件数据,4字节文件长度,4字节文件格式,其后是文件数据 */

byte[] filelength = new byte[4];

byte[] fileformat = new byte[4];

byte[] filebytes = null;

 

/* 从socket流中读取完整文件数据 */

filebytes = receiveFileFromSocket(in, out, filelength,

fileformat);

 

// Log.v(Service139.TAG, "receive data =" + new

// String(filebytes));

try {

/* 生成文件 */

File file = FileHelper.newFile("R0013340.JPG");

FileHelper.writeFile(file, filebytes, 0,

filebytes.length);

} catch (IOException e) {

e.printStackTrace();

}

} else if (currCMD.equals("exit")) {

 

}

} catch (Exception e) {

// try {

// out.write("error".getBytes("utf-8"));

// out.flush();

// } catch (IOException e1) {

// e1.printStackTrace();

// }

Log.e(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "read write error111111");

}

}

out.close();

in.close();

} catch (Exception e) {

Log.e(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "read write error222222");

e.printStackTrace();

} finally {

try {

if (client != null) {

Log.v(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "client.close()");

client.close();

}

} catch (IOException e) {

Log.e(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "read write error333333");

e.printStackTrace();

}

}

}

 

/**

* 功能:从socket流中读取完整文件数据

*

* InputStream in:socket输入流

*

* byte[] filelength: 流的前4个字节存储要转送的文件的字节数

*

* byte[] fileformat:流的前5-8字节存储要转送的文件的格式(如.apk)

*

* */

public static byte[] receiveFileFromSocket(InputStream in,

OutputStream out, byte[] filelength, byte[] fileformat) {

byte[] filebytes = null;// 文件数据

try {

in.read(filelength);// 读文件长度

int filelen = MyUtil.bytesToInt(filelength);// 文件长度从4字节byte[]转成Int

String strtmp = "read file length ok:" + filelen;

out.write(strtmp.getBytes("utf-8"));

out.flush();

 

filebytes = new byte[filelen];

int pos = 0;

int rcvLen = 0;

while ((rcvLen = in.read(filebytes, pos, filelen - pos)) > 0) {

pos += rcvLen;

}

Log.v(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "read file OK:file size=" + filebytes.length);

out.write("read file ok".getBytes("utf-8"));

out.flush();

} catch (Exception e) {

Log.v(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "receiveFileFromSocket error");

e.printStackTrace();

}

return filebytes;

}

 

/* 读取命令 */

public static String readCMDFromSocket(InputStream in) {

int MAX_BUFFER_BYTES = 2048;

String msg = "";

byte[] tempbuffer = new byte[MAX_BUFFER_BYTES];

try {

int numReadedBytes = in.read(tempbuffer, 0, tempbuffer.length);

msg = new String(tempbuffer, 0, numReadedBytes, "utf-8");

tempbuffer = null;

} catch (Exception e) {

Log.v(androidService.TAG, Thread.currentThread().getName()

+ "---->" + "readFromSocket error");

e.printStackTrace();

}

// Log.v(Service139.TAG, "msg=" + msg);

return msg;

}

}

 

后面是两个辅助类:

 

view plaincopy to clipboardprint?

package com.otheri.util;

import java.io.BufferedInputStream;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

import com.otheri.service.androidService;

import android.util.Log;

public class FileHelper {

// private static String FILEPATH = "/data/local/tmp";

private static String FILEPATH = "/sdcard";

// private static String FILEPATH = "/tmp";

public static File newFile(String fileName) {

File file = null;

try {

file = new File(FILEPATH, fileName);

file.delete();

file.createNewFile();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

return file;

}

public static void writeFile(File file, byte[] data, int offset, int count)

throws IOException {

FileOutputStream fos = new FileOutputStream(file, true);

fos.write(data, offset, count);

fos.flush();

fos.close();

}

public static byte[] readFile(String fileName) throws IOException {

File file = new File(FILEPATH, fileName);

file.createNewFile();

FileInputStream fis = new FileInputStream(file);

BufferedInputStream bis = new BufferedInputStream(fis);

int leng = bis.available();

Log.v(androidService.TAG, "filesize = " + leng);

byte[] b = new byte[leng];

bis.read(b, 0, leng);

// Input in = new Input(fis);

// byte[] ret = in.readAll();

// in.close();

bis.close();

return b;

}

}

package com.otheri.util;

 

import java.io.BufferedInputStream;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

 

import com.otheri.service.androidService;

 

import android.util.Log;

 

public class FileHelper {

// private static String FILEPATH = "/data/local/tmp";

 

private static String FILEPATH = "/sdcard";

 

// private static String FILEPATH = "/tmp";

 

public static File newFile(String fileName) {

File file = null;

try {

file = new File(FILEPATH, fileName);

file.delete();

file.createNewFile();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

return file;

}

 

public static void writeFile(File file, byte[] data, int offset, int count)

throws IOException {

 

FileOutputStream fos = new FileOutputStream(file, true);

fos.write(data, offset, count);

fos.flush();

fos.close();

}

 

public static byte[] readFile(String fileName) throws IOException {

File file = new File(FILEPATH, fileName);

file.createNewFile();

FileInputStream fis = new FileInputStream(file);

BufferedInputStream bis = new BufferedInputStream(fis);

int leng = bis.available();

Log.v(androidService.TAG, "filesize = " + leng);

byte[] b = new byte[leng];

bis.read(b, 0, leng);

// Input in = new Input(fis);

// byte[] ret = in.readAll();

// in.close();

bis.close();

return b;

 

}

}

 

view plaincopy to clipboardprint?

package com.otheri.util;

import java.io.InputStream;

import android.util.Log;

import com.otheri.service.androidService;

public class MyUtil {

/* byte[]转Int */

public static int bytesToInt(byte[] bytes) {

int addr = bytes[0] & 0xFF;

addr |= ((bytes[1] << 8) & 0xFF00);

addr |= ((bytes[2] << 16) & 0xFF0000);

addr |= ((bytes[3] << 24) & 0xFF000000);

return addr;

}

/* Int转byte[] */

public static byte[] intToByte(int i) {

byte[] abyte0 = new byte[4];

abyte0[0] = (byte) (0xff & i);

abyte0[1] = (byte) ((0xff00 & i) >> 8);

abyte0[2] = (byte) ((0xff0000 & i) >> 16);

abyte0[3] = (byte) ((0xff000000 & i) >> 24);

return abyte0;

}

}

 

 

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/wufenglong/archive/2010/07/31/5778862.aspx

本文标签

除非注明,文章均为( noway )原创,转载请保留链接: http://blog-old.z3a105.com/?p=784

PC客户端与Android服务端的Socket同步通信(USB):等您坐沙发呢!

发表评论





       ==QQ:122320466==

 微信    QQ群


0

Aujourd’hui, une partie avec le développement du e-commerce, achats en ligne est devenu une partie de la vie pour beaucoup de gens. La mariage a commencé achats en ligne. Si vous choisissez achats les mariages en ligne, il peut être beaucoup moins cher que le salon de la Robe de mariée pas chermariée local, réduisant le budget de mariage. vous pouvez avoir beaucoup de choix si acheter de mariage en ligne. vous pouvez ramasser une robe de mariée bon marché sur Internet.
Piercing fascinerande figur, och nu tittar vi på 2016 senast brudklänning, kan du vara den vackraste bruden det!2016 senaste Bra brudklänning, söt temperament Bra design, romantiska spetsar blomma kjol, som du lägger till en elegant och charmig temperament.Kvinnan tillbaka mjuka linjer, människor brudklänningofta få en känsla av oändlig frestelse. Fall 2016 mässan, lämnar uppgifter om ditt bröllop charmig.
Yesterday afternoon, the Chinese team was training in the Guangzhou Gymnasium, when the reporter asked Zhao Yunlei the feeling of wearing the new cheap jersey , cheap jerseys online shopshe readily took a shirt from the bag crumpled ball to reporters, and she said with a smile: ” This shirt is light. ”Zhao Yunlei said: “Our material is very light like with the clothes of the tennis King Nadal, Federer, after the sweat, sweat does not drip down to the ground, when we do move, it is easy pace slipping if the sweat drip on the floor.”Tennis players Zhang Yawen, told reporters: “You might think the clothes attached to the body, fearing we swing will be affected, in fact, we do not feel anything, because the clothes are very light, very soft, put on quite comfortable. And it’s particularly good clothes to dry, washing and will dry in 15 minutes. ”
China’s sports enthusiasts NFL sweatshirt with mad love and the pursuit of, and therefore, NFL jerseys have a good market in China and development. China is a populous country, is the consumer, the economic momentum is so good, the sales prospects sportswear is immeasurable. With hot sales sweatshirt, but also to promote the importance of sports fans, on health, on the other hand is a matter of concern for the World Cup, fans wearing NFL jerseys and also can express themselves more fully love and obsession Therefore, NFL jerseys Wholesale jerseys online shopwholesale has good prospects and development in China.
ANTA-ANTA Sports Products Limited, referred to as ANTA Sports, Anta, is China’s leading sporting goods companies, mainly engaged in the design, development, manufacture and marketing of ANTA brand sporting goods, including sports footwear, apparel and accessories. Anta sweatshirt design advantages, warm stretch knit fabric, using Slim version of model, more personal fit, bid farewell to bloated, so wearing more stylish.GUIRENNIAO-This logo is a spiritual totem, smooth graphics implication unstoppable force; flexible deliver an elegant arc Wholesale jerseys china shop movement, strength and speed of the United States, a symbol of passion and rationality publicity “Heart” and “meaning”, “concept” unity; pass the fearless and enterprising mind, showing beyond the realm of self, to unstoppable force to create the future.XTEP-Xtep (China) Co., Ltd. is a comprehensive development wholesale jerseys china shop, production and marketing of Xtep brand (XTEP) sports shoes, clothing, bags, caps, balls, socks mainly large sporting goods industry enterprises.
There are a lot of fans in identifying the authenticity of the above cheap jerseys have great distress, so here to i will show you some methods to definitely affordable inexpensive cheap jerseys : Firstly, we should look at if it is working fine. China has been called the world’s factory, a lot cheap jerseys factories in China have foundries, but our cheap jerseys are all from here! Secondly, should to see whether it is the , we all know that it is difficult to get out of print once a genuine cheap cheap jerseys free shipping jersey was print. and we have all kind of stocka on the whole website, in other words, we have all you want ! Finally, look at the price, our price is not necessarily the lowest in the whole website but it must be most fair on the whole website, we certainly you will not regret later when you buy it. Of course, except that cheap jerseys, we also have the other products, such as socks, leggings and some other related products, everyone can enjoy the best services of here!

KUBET