转载请写明出处:http://blog.youkuaiyun.com/csdn1073044009
Android与服务器的通信方式主要有两种,一是Http通信,二是Socket通信。
http通信 使用的是“请求—响应方式”,在请求时建立连接通道,当客户端向服务器发送请求后,服务器端才能向客户端返回数据。
Socket通信 是在双方建立起连接后就可以直接进行数据的传输,在连接时可实现信息的主动推送,而不需要每次由客户端想服务器发送请求。Socket提供了程序内部与外界通信的端口并为通信双方的提供了数据传输通道。
Socket常用的有两种实现原理:基于TCP和UDP,我这里是写了一个自己比较熟悉的基于TCP协议的Socket,是一个简单地聊天的项目代码,希望对你们有所帮助,分客户端和服务端。
首先是客户端:
public class MainActivity extends Activity {
// 声明组件
private EditText editIp, editMsg;
private Button btnConnect, btnSend;
private ListView lv;
private ArrayAdapter<String> adapter;
//存储聊天记录
private List<String> messages=new ArrayList<String>();
//将流声明成成员变量
private DataInputStream dis;
private DataOutputStream dos;
Socket socket;
//更新UI --handler
private Handler hand =new Handler(){
public void handleMessage(Message msg)
{
adapter.notifyDataSetChanged();
lv.setSelection(messages.size()-1);
};
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 初始化组件
init();
//lsitview 数据绑定
setAdapter();
}
//添加按钮的单击事件
public void click(View v){
switch (v.getId()) {
case R.id.button1://连接
if(socket!=null){
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
new Thread(new Runnable() {
public void run() {
conect();
new WorkThread().start();
}
}).start();
break;
case R.id.button2://发送
sendMsg();
break;
}
}
/**
* listview 数据绑定
*/
private void setAdapter() {
adapter=new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, messages);
lv.setAdapter(adapter);
}
/**
* 数据初始化
*/
private void init() {
editIp=(EditText) findViewById(R.id.editText1);
editMsg=(EditText) findViewById(R.id.editText2);
btnConnect= (Button) findViewById(R.id.button1);
btnSend= (Button) findViewById(R.id.button1);
lv= (ListView) findViewById(R.id.listView1);
}
//连接聊天室
public void conect(){
String ip=editIp.getText().toString();
try {
socket=new Socket(ip,6666);
//获取流
dis=new DataInputStream(socket.getInputStream());
dos=new DataOutputStream(socket.getOutputStream());
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//给服务端发消息
public void sendMsg(){
//内容
String str=editMsg.getText().toString();
//流
try {
dos.writeUTF(str);
dos.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//接收消息更新到界面
class WorkThread extends Thread{
@Override
public void run() {
super.run();
//不断读服务器的消息
while(true){
try {
String msg=dis.readUTF();
messages.add(msg);
hand.sendEmptyMessage(0);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if(socket!=null){
try {
dos.close();
dis.close();
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
然后是<span style="color:#ff0000;">服务端:</span>
<pre name="code" class="java">public class ChatSer {
// 声明list集合存储连接过来的客户端套接字
List<Socket> list = new ArrayList<>();
// 处理客户端连接————支持多客户端连接
public void connect() {
try {
ServerSocket ser = new ServerSocket(6666);
while (true) {
Socket socket = ser.accept();
list.add(socket);
// 为每个客户端开辟一个线程
System.out.println("客户端登录成功");
new WorkThread(socket).start();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// 创建工作线程 --->处理业务交互
class WorkThread extends Thread {
// 通过构造方法将socket传递进来
private Socket socket;
// 构造器
public WorkThread(Socket socket) {
super();
this.socket = socket;
}
@Override
public void run() {
super.run();
// 获取流
try {
DataInputStream dis = new DataInputStream(socket.getInputStream());
while (true) {
String msg = dis.readUTF();
for (int i = 0; i <list.size(); i++) {
DataOutputStream dos = new DataOutputStream(list.get(i).getOutputStream());
dos.writeUTF(msg);
dos.flush();
}
}
} catch (IOException e) {
e.printStackTrace();
list.remove(socket);
}
}
}
public static void main(String[] args) {
new ChatSer().connect();
}
}<span style="color:#ff0000;">
</span>
最后别忘了,如果想要运行程序,别忘了在清单文件中加上:<uses-permission android:name="android.permission.INTERNET"/>
<span style="color:#ff0000;">端口号一定要对应正确无误!</span>
这样的话,小伙伴们Socket通信相信自己可以琢磨着写出来了^ _ ^