编写Android端TCP服务器遇到的问题
2017-01-10 14:59
351 查看
最近写了一个小的apk 将遇到的问题总结下
1、关于在线程中无法更新UI控件的问题
答:在主线程是可以更新UI控件(包括Toast都不行),但子线程便不行 解决的方法是添加runOnUiThread
runOnUiThread(new Runnable() {
public void run() {
showTip(receiveInfoServer);//不可在线程中更新UI,需添加runOnUiThread,
}
});
2、关于线程中嵌套线程
答:在TCP开始监听按钮中 启动监听监听线程,在监听线程中启动接收线程
// 开始监听按钮
listenBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
*//**
* 启动服务器监听线程
*//*
if (isListened) {
isListened = false;
try {
if (serverSocket != null) {
serverSocket.close();
serverSocket = null;
inputstream.close();
outputStream.close();
inputstream = null;
outputStream = null;
}
} catch (Exception e) {
e.printStackTrace();
}
new ServerSocket_thread().interrupt();// 监听中断
listenBtn.setText("开始监听");
localPortEdt.setEnabled(true);
removeItem();// 移除list表中的内容
} else {
isListened = true;
if (isListened && (serverSocket == null)) {
new ServerSocket_thread().start();
listenBtn.setText("停止监听");
localPortEdt.setEnabled(false);
}
}
}
});
/**
* 服务器监听线程
*/
class ServerSocket_thread extends Thread {
public void run()// 重写Thread的run方法
{
try {
int port = Integer.parseInt(localPortEdt.getText().toString());// 获取监听的端口号
serverSocket = new ServerSocket(port);// 监听port端口,这个程序的通信端口就是port了
receiveInfoServer = "开始监听!" + localIpEdt.getText().toString()
+ ":" + "(本机地址端口)" + localPortEdt.getText().toString()
+ "\n";
runOnUiThread(new Runnable() {
public void run() {
showTip(receiveInfoServer);//不可在线程中更新UI,需添加runOnUiThread
}
});
} catch (IOException e) {
e.printStackTrace();
}
while (isListened) {
try {
// 监听连接 ,如果无连接就会处于阻塞状态,一直在这等着
socket = serverSocket.accept();
String clientIP = socket.getInetAddress().toString();
int clientPort = socket.getPort();
clientIP = clientIP
.substring(clientIP.lastIndexOf("/") + 1);// 去除"/"线
receiveInfoServer = "连接客户端成功!" + "客户端IP地址:" + clientIP
+ "客户端端口" + clientPort + "\n";
runOnUiThread(new Runnable() {
@Override
public void run() {
// TODO 自动生成的方法存根
showTip(receiveInfoServer);
}
});
Log.e("客户端连接", receiveInfoServer);
inputstream = socket.getInputStream();//
// 启动接收线程
Receive_Thread receive_Thread = new Receive_Thread();
receive_Thread.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
*
* 接收线程
*
*/
class Receive_Thread extends Thread// 继承Thread
{
final byte[] buf = new byte[1024];
int len = 0;
Socket clientSocket = socket;
public void run()// 重写run方法
{
while (isListened) {
try {
if ((len = inputstream.read(buf)) > 0)// 接收到客户端的数据,说明还在线
{
runOnUiThread(new Runnable() {
public void run() {
String reciveString = new String(buf, 0, len);
dealMessage(reciveString, clientSocket);
Log.e("@@@@",
"客户端" + clientSocket + "接收数据"
+ reciveString + "长度"
+ reciveString.length());
}
});
} else {
Log.e("@@@@", "客户端掉线了" + clientSocket);
// 删除list列表中断开的客户端
runOnUiThread(new Runnable() {
@Override
public void run() {
deleteSocketList(clientSocket);//客户端掉线后,删除listview中相关的数据
}
});
return;
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
3、关于各种数据的转化
// str 转16进制字符串
public static String str2HexStr(String str) {
char[] chars = "0123456789ABCDEF".toCharArray();
StringBuilder sb = new StringBuilder("");
byte[] bs = str.getBytes();
int bit;
for (int i = 0; i < bs.length; i++) {
bit = (bs[i] & 0x0f0) >> 4;
sb.append(chars[bit]);
bit = bs[i] & 0x0f;
sb.append(chars[bit]);
// sb.append(' ');
}
return sb.toString().trim();
}
// 16进制转十进制字节
public static byte[] hexStringToByte(String hex) {
int len = (hex.length() / 2);
byte[] result = new byte[len];
char[] achar = hex.toCharArray();
for (int i = 0; i < len; i++) {
int pos = i * 2;
result[i] = (byte) (toByte(achar[pos]) << 4 | toByte(achar[pos + 1]));
}
return result;
}
private static byte toByte(char c) {
byte b = (byte) "0123456789ABCDEF".indexOf(c);
return b;
}
//string转ASCII码
private String stringToAscii(String value) { StringBuffer sbu = new
StringBuffer(); char[] chars = value.toCharArray(); for (int i = 0; i <
chars.length; i++) { if(i != chars.length - 1) {
sbu.append((int)chars[i]).append(","); } else {
sbu.append((int)chars[i]); } } return sbu.toString(); }
1、关于在线程中无法更新UI控件的问题
答:在主线程是可以更新UI控件(包括Toast都不行),但子线程便不行 解决的方法是添加runOnUiThread
runOnUiThread(new Runnable() {
public void run() {
showTip(receiveInfoServer);//不可在线程中更新UI,需添加runOnUiThread,
}
});
2、关于线程中嵌套线程
答:在TCP开始监听按钮中 启动监听监听线程,在监听线程中启动接收线程
// 开始监听按钮
listenBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
*//**
* 启动服务器监听线程
*//*
if (isListened) {
isListened = false;
try {
if (serverSocket != null) {
serverSocket.close();
serverSocket = null;
inputstream.close();
outputStream.close();
inputstream = null;
outputStream = null;
}
} catch (Exception e) {
e.printStackTrace();
}
new ServerSocket_thread().interrupt();// 监听中断
listenBtn.setText("开始监听");
localPortEdt.setEnabled(true);
removeItem();// 移除list表中的内容
} else {
isListened = true;
if (isListened && (serverSocket == null)) {
new ServerSocket_thread().start();
listenBtn.setText("停止监听");
localPortEdt.setEnabled(false);
}
}
}
});
/**
* 服务器监听线程
*/
class ServerSocket_thread extends Thread {
public void run()// 重写Thread的run方法
{
try {
int port = Integer.parseInt(localPortEdt.getText().toString());// 获取监听的端口号
serverSocket = new ServerSocket(port);// 监听port端口,这个程序的通信端口就是port了
receiveInfoServer = "开始监听!" + localIpEdt.getText().toString()
+ ":" + "(本机地址端口)" + localPortEdt.getText().toString()
+ "\n";
runOnUiThread(new Runnable() {
public void run() {
showTip(receiveInfoServer);//不可在线程中更新UI,需添加runOnUiThread
}
});
} catch (IOException e) {
e.printStackTrace();
}
while (isListened) {
try {
// 监听连接 ,如果无连接就会处于阻塞状态,一直在这等着
socket = serverSocket.accept();
String clientIP = socket.getInetAddress().toString();
int clientPort = socket.getPort();
clientIP = clientIP
.substring(clientIP.lastIndexOf("/") + 1);// 去除"/"线
receiveInfoServer = "连接客户端成功!" + "客户端IP地址:" + clientIP
+ "客户端端口" + clientPort + "\n";
runOnUiThread(new Runnable() {
@Override
public void run() {
// TODO 自动生成的方法存根
showTip(receiveInfoServer);
}
});
Log.e("客户端连接", receiveInfoServer);
inputstream = socket.getInputStream();//
// 启动接收线程
Receive_Thread receive_Thread = new Receive_Thread();
receive_Thread.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
*
* 接收线程
*
*/
class Receive_Thread extends Thread// 继承Thread
{
final byte[] buf = new byte[1024];
int len = 0;
Socket clientSocket = socket;
public void run()// 重写run方法
{
while (isListened) {
try {
if ((len = inputstream.read(buf)) > 0)// 接收到客户端的数据,说明还在线
{
runOnUiThread(new Runnable() {
public void run() {
String reciveString = new String(buf, 0, len);
dealMessage(reciveString, clientSocket);
Log.e("@@@@",
"客户端" + clientSocket + "接收数据"
+ reciveString + "长度"
+ reciveString.length());
}
});
} else {
Log.e("@@@@", "客户端掉线了" + clientSocket);
// 删除list列表中断开的客户端
runOnUiThread(new Runnable() {
@Override
public void run() {
deleteSocketList(clientSocket);//客户端掉线后,删除listview中相关的数据
}
});
return;
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
3、关于各种数据的转化
// str 转16进制字符串
public static String str2HexStr(String str) {
char[] chars = "0123456789ABCDEF".toCharArray();
StringBuilder sb = new StringBuilder("");
byte[] bs = str.getBytes();
int bit;
for (int i = 0; i < bs.length; i++) {
bit = (bs[i] & 0x0f0) >> 4;
sb.append(chars[bit]);
bit = bs[i] & 0x0f;
sb.append(chars[bit]);
// sb.append(' ');
}
return sb.toString().trim();
}
// 16进制转十进制字节
public static byte[] hexStringToByte(String hex) {
int len = (hex.length() / 2);
byte[] result = new byte[len];
char[] achar = hex.toCharArray();
for (int i = 0; i < len; i++) {
int pos = i * 2;
result[i] = (byte) (toByte(achar[pos]) << 4 | toByte(achar[pos + 1]));
}
return result;
}
private static byte toByte(char c) {
byte b = (byte) "0123456789ABCDEF".indexOf(c);
return b;
}
//string转ASCII码
private String stringToAscii(String value) { StringBuffer sbu = new
StringBuffer(); char[] chars = value.toCharArray(); for (int i = 0; i <
chars.length; i++) { if(i != chars.length - 1) {
sbu.append((int)chars[i]).append(","); } else {
sbu.append((int)chars[i]); } } return sbu.toString(); }
相关文章推荐
- 使用netty4.x 编写TCP服务器关于握手问题
- 编写一个Android平台遇到的所有问题(一)——查询sqlite数据库时遇到的问题
- Android开发中与服务器交互时,遇到java.io.IOException: Target host must not be null的问题
- Android通过webservice连接SQLServer 详细教程以及所遇到的问题解答(数据库+服务器+客户端)
- 图像检索服务器编写问题记录——TCP粘包了!!!
- 解决Android客户端运行Cococs2dx编写的游戏程序遇到的意外游戏中断导致的游戏黑屏问题
- Socket 通信原理(Android客户端和服务器以TCP&&UDP方式互通)(解决不可连的问题,解决方案在最后面)
- 使用netty4.x 编写UDP服务器遇到的狗血问题
- Android实现支付宝支付遇到的问题记录--主要是和服务器的合作上
- Android客户端,PC服务器,Socket连接所遇到的问题
- 编写android加载图片的程序时,遇到了内存泄露问题!
- android中使用ksoap2和服务器传递对象遇到的问题
- 2018/3/4-3/6个人android客户端和服务器通信学习总结--主要是网上聊天局域网通信例子及环境搭配遇到的问题
- 关于编写android程序遇到的问题
- 编写android jni代码时遇到的问题
- 编写Android app更新模块遇到的问题分析与总结
- 2014.10.7编写Android代码遇到的问题
- 编写Android时遇到的问题
- android使用CMake进行jni编写遇到的一些问题
- 编写Android app更新模块遇到的问题分析与总结