在学习Socket之前,我们需要掌握一些知识,如java多线程,Handler等.
Java多线程
https://blog.csdn.net/qq_40318498/article/details/84726026
C#Socket通信
https://blog.csdn.net/qq_40318498/article/details/90384688
Android Handler消息处理
https://blog.csdn.net/qq_40318498/article/details/89897690
源码已上传到github上
https://github.com/Githubforusc2018/AndroidSocket
使用技术
1.Handler 2.多线程 3.网络编程
Android登录界面截图
Android客户端界面截图
Android服务端界面截图
Client客户端核心代码
int port
= Integer
.parseInt(clientPort
.getText().toString());
mysocket
= new Socket(clientIp
.getText().toString(),port
);
while(true){
InputStream is
= mysocket
.getInputStream();
byte[] buffer
= new byte[1024*1024];
int len
= is
.read(buffer
);
String result
= new String(buffer
, 0, len
);
if (mycount
++==1){
myIp
= result
;
}
Message message
= new Message();
message
.what
= 1;
Bundle bundle
= new Bundle();
bundle
.putString("msg", result
);
message
.setData(bundle
);
handler
.sendMessage(message
);
}
DataOutputStream writer
= new DataOutputStream(mysocket
.getOutputStream());
writer
.write(clientMessage
.getText().toString().getBytes());
Message message
= new Message();
message
.what
= 1;
Bundle bundle
= new Bundle();
bundle
.putString("msg", myIp
+" : "+clientMessage
.getText().toString());
message
.setData(bundle
);
handler
.sendMessage(message
);
public Handler handler
= new Handler(){
@Override
public void handleMessage(Message msg
) {
super.handleMessage(msg
);
if (msg
.what
==1){
Bundle data
= msg
.getData();
sb
.append(data
.getString("msg"));
sb
.append("\n");
serverMessageText
.setText(sb
.toString());
}
}
};
Server服务端端核心代码
serverSocket
= new ServerSocket(50000);
clientSocket
= serverSocket
.accept();
while(true){
InputStream is
= clientSocket
.getInputStream();
byte[] buffer
= new byte[1024*1024];
int len
= is
.read(buffer
);
String result
= new String(buffer
, 0, len
);
Message message
= new Message();
Bundle bundle
= new Bundle();
bundle
.putString("msg",result
);
message
.setData(bundle
);
message
.what
= 1;
handler
.sendMessage(message
);
}
OutputStream writer
= clientSocket
.getOutputStream();
writer
.write(normalMessage
.getText().toString().getBytes());
String result
= "发送成功";
Message message
= new Message();
Bundle bundle
= new Bundle();
bundle
.putString("msg",result
);
message
.setData(bundle
);
message
.what
=1;
handler
.sendMessage(message
);
@SuppressLint("HandlerLeak")
public Handler handler
= new Handler(){
@Override
public void handleMessage(Message msg
) {
super.handleMessage(msg
);
if (msg
.what
==1){
Bundle data
= msg
.getData();
sb
.append(data
.getString("msg"));
sb
.append("\n");
normalText
.setText(sb
.toString());
}
}
};
主界面中的图片切换动作使用handler处理和动画处理. ListView客户端和ListView服务端在以上基础上,使用listview组件来显示消息,这里我对格式弄了一个处理,因此可能无法使用ListView客户端来与c#客户端进行数据交换,而只能使用Android与Android进行通信,可以解决该问题,如下.
String result
= userText
.getText().toString() + "-" + classText
.getText().toString() + "-" + ageText
.getText().toString();
writer
.write(result
.getBytes());
Text
= result
.split("-");
HashMap
<String,Object> map
= new HashMap<String, Object>();
map
.put("User",Text
[0]);
map
.put("Class",Text
[1]);
map
.put("Age",Text
[2]);
mylist
.add(map
);
int i
=0;
for(i
=0;i
<result
.length();i
++){
if (result
.charAt(i
)=='-'){
break;
}
}
if (i
==result
.length()){
Text
[0] = result
;
Text
[1] = "null";
Text
[2] = "null";
}else{
Text
= result
.split("-");
}
Java split测试
一些总结:
1.服务端(假设是模拟机)可以向手机(服务端)发送请求连接,因此知道手机的ip地址能够正常连接,而手机客户端无法通过电脑的ip地址访问到模拟机(服务端),若要连接,需要知道模拟机的ip地址.
2.一个Message只能传给一个handler,若要使用handler处理多个任务,需要初始化多个Message.
3.可以使用bundle向handler中(可以是同一个活动)传递数据,在handler中使用Bundle bundle = msg.getData()来获取数据。
4.在退出活动的时候,需要关闭I/O流和socket连接.
5.使用5个write,怎么第一个输出有换行,明明程序中没有换行,最后写成一行可以解决该问题. (若不写成一个write,可以通过trim()方法去掉多余的空格和换行)
6.Handler是Android提供的一个用来更新UI的机制(Android不允许在子线程更新UI),也是一个消息处理的机制
7.一些超时的任务处理,如网络下载等需要使用子线程来完成,因此默认情况下,主线程等待5s以上就会关闭该活动。
功能:
1.在C#Socket通信的基础上,增加Android Socket通信 2.能够让Android跟C#通信 3.能够让Android与Android进行通信.