使用android进行Socket通信实现多人聊天应用

先看一下效果图

使用Socket实现多人聊天应用

 

在讲scoket通信器先可以先了解一下网络协议

手机能够使用联网功能是因为手机底层实现了TCP/IP协议,可以使手机终端通过无线网络建立TCP连接。TCP协议可以对上层网络提供接口,使上层网络数据的传输建立在“无差别”的网络之上。可以将网络协议分为四层,从高到低依次为:应用层、传输层、网络层、链路层。

 

两种Socket类型的基本通信

TCP是一个可靠的、面向连接的协议。它可以保证数据从连接的一方传递到另一方,并且发送数据的顺序和所接收数据的顺序一致。当应用程序需要一个可靠的、点对点的连接时,可以使用TCP。

UDP是一种不可靠的通信协议,没有检测错误的机制,也不重发丢失的数据。接收到的数据包的顺序可能与发送的数据包的顺序不一致。采用UDP进行通信时,事先不需要建立连接。而采用TCP进行通信时,首先要建立一个连接。TCP的通信质量比UDP高,UDP的开销比TCP小。

 

这里我们以TCP协议为主

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

Socket套接字概念

 套接字(socket)是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元。它是网络通信过程中端点的抽象表示,包含进行网络通信必须的五种信息:连接使用的协议,本地主机的IP地址,本地进程的协议端口,远地主机的IP地址,远地进程的协议端口。

先看一下TCP通信的步骤:

建立Socket连接

•       连接过程分为三个步骤:

–      服务端监听

–      客户端请求

–      连接确认

(多线程机制,各个客户端和服务器之间的通信)

–      服务端:ServerSocket

–      客户端:Socket

–      信息传输:

•      发送信息getoutputsream()   write();

•      接收信息getinputstream()    read();

案例:

使用TCP协议通信

 java服务端,此时是使用java做服务端

ScoketDemo .java

package scoket.activity;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

public class ScoketDemo {
	public static List<Socket> clients = new ArrayList<Socket>();// 创建一个集合存放所有的客户端

	/**
	 * @param args
	 * @throws IOException
	 */
	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		ServerSocket ss;
		while (true) {
			ss = new ServerSocket(2019);
			Socket s = ss.accept();// 使服务端处于监听状态

			clients.add(s);
			// 为每一个客户端开设一个单个线程
			new ChatThread(s).start();

			// OutputStream os=client.getOutputStream();
			// os.write("Nice to meet you!".getBytes("utf-8"));
			// os.close();//网络编程流的关闭是按栈的方式关闭的
			// client.close();
		}
		// No enclosing instance of type ScoketDemo is accessible. Must qualify
		// the allocation
		// with an enclosing instance of type
		// ScoketDemo (e.g. x.new A() where x is an instance of ScoketDemo).
	}

	public static class ChatThread extends Thread {

		Socket client;
		BufferedReader br;

		public ChatThread(Socket c) {
			super();
			this.client = c;

			try {
				br = new BufferedReader(new InputStreamReader(
						client.getInputStream(), "UTF-8"));// 将客户端对象封装一下
			} catch (UnsupportedEncodingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}

		@Override
		public void run() {
			// TODO Auto-generated method stub
			super.run();
			String content = null;
			// 获取客户端传递过来的数据
			try {
				while ((content = br.readLine()) != null) {
					// 再将服务端的数据返回给客户端
					OutputStream os = client.getOutputStream();
					os.write(content.getBytes("utf-8"));
				}
			} catch (UnsupportedEncodingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

	}
}


android客户端

ChatScoketDemoActivity.java

package com.scoket.activity;

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

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;

public class ChatScoketDemoActivity extends Activity implements OnClickListener {
	/** Called when the activity is first created. */
	private EditText name, setence, show;
	private Button btn;
	Socket client;
	Handler myHandler = new Handler() {
		public void handleMessage(android.os.Message msg) {
			if (msg.what==123) {
				String str = show.getText().toString();
				show.setText(str +"\n"+ msg.getData().getString("chat"));
			}
			 
		};
	};

	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		btn = (Button) findViewById(R.id.button1);
		name = (EditText) findViewById(R.id.name);
		setence = (EditText) findViewById(R.id.setence);
		show = (EditText) findViewById(R.id.show);

		btn.setOnClickListener(this);
		new Thread(new Runnable() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				try {
					client = new Socket("172.20.52.26", 2019);// 网络访问最好放在线程中
					new chatThread(client).start();// 启动子线程
				} catch (UnknownHostException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}).start();
          
	}

	@Override
	public void onClick(View arg0) {
		// TODO Auto-generated method stub
		String s1 = name.getText().toString();
		String s2 = setence.getText().toString();
		String s3 = s1 + ":" + s2+"\n";
		if (client != null) {
			try {
				client.getOutputStream().write(s3.getBytes("utf-8"));// 获取从客户端得到的数据
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		} //setence.setText("");//相当于刷新
	}

	class chatThread extends Thread {
		Socket s;

		public chatThread(Socket s) {
			super();
			this.s = s;
		}

		@Override
		public void run() {

			try {
				BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
				while (true) {
					String content = br.readLine();
					if (content != null) {
						Bundle bundle = new Bundle();
						bundle.putString("chat", content);
						Message msg = new Message();
						msg.setData(bundle);
						msg.what=123;
						myHandler.sendMessage(msg);
					}

				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

	}
}

源码

猜你喜欢

转载自blog.csdn.net/mxcsdn/article/details/51495825