Android---51---加入多线程进行Socket通信

前面服务器和客户端只是进行了简单的通信操作:服务器接收到客户端连接之后

服务器向客户端输出一个字符串,而客户端也只是读取服务器的字符串之后就退出了

而实际 应用中的客户端则可能需要和服务器保持长时间的通信,即服务器

需要不断的读取客户端的数据,并向客户端写入数据;客户端也需要不断的

读取服务器,并向数据库中写入数据。

使用传统BufferedReader的 readLine 方法读取数据时,当该方法成功返回之前,该线程

是阻塞的,程序无法继续进行。所以,服务器应该为每一个Socket开启一个线程,每条线程

负责与一个客户端进行通信。

服务器端:

class ServerThread implements Runnable {

	Socket s;
	BufferedReader br;

	public ServerThread(Socket s) throws IOException {
		super();
		this.s = s;
		br = new BufferedReader(new InputStreamReader(s.getInputStream()));
	}

	@Override
	public void run() {
		String content = null;
		try {
			while ((content = readFromClient()) != null) {
				for (Socket s : MultiThreadServer.sockets) {
					OutputStream os;
					os = s.getOutputStream();
					os.write((content + "\n").getBytes("utf-8"));

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

	private String readFromClient() {
		try {
			return br.readLine();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

}

public class MultiThreadServer {

	public static ArrayList<Socket> sockets = new ArrayList<Socket>();

	public static void main(String[] args) throws IOException {
		ServerSocket ss = new ServerSocket(45623);
		while (true) {
			Socket s = ss.accept();
			sockets.add(s);
			new Thread(new ServerThread(s)).start();
		}
	}
}

每当客户端Socket连接到该ServerSocket之后,

程序将对应Socket加入到集合中保存,并为该Socket开启一条线程,负责处理该Socket的

所有通信事务。

客户端:

MultiClient:

public class MultiThreadClient extends Activity {

	EditText input;
	TextView show;
	Button send;
	Handler handler;
	ClientThread clientThread;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_client_thread);

		input = (EditText) findViewById(R.id.input);
		show = (TextView) findViewById(R.id.show);
		send = (Button) findViewById(R.id.send);

		handler = new Handler() {
			@Override
			public void handleMessage(Message msg) {
				// 如果消息来自于子线程
				if (msg.what == 0x123) {
					// 将读取的内容追加显示在文本中
					show.append("\n" + msg.obj.toString());
				}
			}
		};

		clientThread = new ClientThread(handler);
		// 客户端启动ClientThread线程创建网络连接、读取来自服务器的数据
		new Thread(clientThread).start();

		send.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				// 当用户按下发送按钮后,将用户输入的数据封装成Message,然后发送给子线程的handler
				Message msg = new Message();
				msg.what = 0x345;
				msg.obj = input.getText().toString();
				clientThread.revHandler.sendMessage(msg);
				input.setText("");
			}
		});
	}
}

ClientThread:

public class ClientThread implements Runnable {

	private Socket s;
	// 定义向UI线程发送消息的Handler对象。
	private Handler handler;
	// 定义接收UI线程的消息的Handler对象.
	public Handler revHandler;
	// 该线程所处理的Socket所对用的流对象
	BufferedReader br;
	OutputStream os;

	public ClientThread(Handler handler) {
		super();
		this.handler = handler;
	}

	@Override
	public void run() {
		try {
			s = new Socket("192.168.3.12", 45623);
			br = new BufferedReader(new InputStreamReader(s.getInputStream()));
			os = s.getOutputStream();
			// 启动一条子线程
			new Thread() {
				public void run() {
					String content = null;
					// 不断读取Socket输入流中的内容
					try {
						while ((content = br.readLine()) != null) {
							// 每当读到来自服务器的数据之后,发送消息通知程序界面显示该数据
							Message msg = new Message();
							msg.what = 0x123;
							msg.obj = content;
							handler.sendMessage(msg);

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

			// 为当前线程初始化Looper
			Looper.prepare();
			// 创建revhandler对象
			revHandler = new Handler() {
				@Override
				public void handleMessage(Message msg) {
					// 接收UI线程中用户输入的数据
					if (msg.what == 0x345) {
						// 将用户在文本框内输入的内容写入网络
						try {
							os.write((msg.obj.toString() + "\r\n").getBytes("utf-8"));
						} catch (IOException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
				}
			};

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

	}
}
时间: 2024-11-04 18:06:35

Android---51---加入多线程进行Socket通信的相关文章

Android客户端与本地服务器Socket通信

Android客户端与本地服务器Socket通信 Socket服务器运行结果图?? 一.客户端和服务器端的选择: 客户端是我们手机端,关于服务器端,只要安装了JDK,自然就拥有通讯的功能,我们只需要在Eclipse或者MyEclipse中写好文章中服务器端的代码,运行起来即可,用accept()方法启动服务器端,等待客户端的连接,在未连接的情况下,服务器端处于堵塞的状态. 二.客户端注意事项 andriod客户端添加网络访问权限 <uses-permission android:name="

利用ddmlib 实现 PC端与android手机端adb forword socket通信(转)

上篇文章讲了PC与android手机连接的办法 ,通过java调用系统命令执行adb命令操作,实际上是一个比较笨的办法. 网上查阅资料,发现google 提供了ddmlib库 (adt-bundle\sdk\tools 目录下), 提供了adb相关操作的所有api. 文档参考 http://www.jarvana.com/jarvana/view/com/google/android/tools/ddmlib/r13/ddmlib-r13-javadoc.jar!/index.html 参考范例

一个多线程的Socket通信Demo(C语言实现)

-----------这是客户端程序-------------- #include "stdio.h" #include "winsock2.h" #include "stdlib.h" #pragma comment(lib,"ws2_32") void main() {     WSADATA wsaData;     WSAStartup(MAKEWORD(2,2),&wsaData);     SOCKET s

Android网络编程之Socket通信

Socket(套接字)是一种通信机制,可以实现单机或跨网络进行通信,其创建需要明确的区分C(客户端)/S(服务器端),支持多个客户端连接到同一个服务器.有两种传输模式: 1).面向连接的传输:基于TCP协议,可靠性高,但效率低: 2).面向无连接的传输:基于UDP协议,可靠性低,但效率高: Android中,直接采用Socket通信应该是我们遇到的最低级的网络运用.尽管已经作了很大程度的抽象,但是纯粹的Socket通信,仍然给开发者留下很多细节需要处理,尤其在服务器端,开发者需要处理多线程以及数

android的NDK和java进行本地socket通信

关于Android应用与Framework的socket通信,相信关心这个问题的朋友们已经看过<android使用socket使底层和framework通信>这篇文章,美中不足的是作者只贴出一些关键的代码片段而并没有放出源码.我这里还是以一个能实际运行的例子为基础来讲,这样也方便大家学习. 首先看一下效果,如下图.我填写姓名"Potter",选择性别"Mr"然后点击发送,底层socket收到消息后将消息直接返回给我,我将返回的结果(Mr.Potter)直

Android简单Socket通信demo

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

C#socket通信-----多线程

我在之前的socket通信的基础上做了一点改进,使用多线程来使用,程序更加简洁实用.不足之处请指教哦! 话不多说,之前的随笔也有介绍,直接上代码啦! 服务端socket(serverSocket): 1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 using System.Net; 7 us

Android开发笔记(一百一十一)聊天室中的Socket通信

Socket通信 基本概念 对于程序开发来说,网络通信的基础就是Socket,但因为是基础,所以用起来不容易,今天我们就来谈谈Socket通信.计算机网络有个大名鼎鼎的TCP/IP协议,普通用户在电脑上设置本地连接的ip时,便经常看到下图的弹窗,注意红框部分已经很好地描述了TCP/IP协议的作用. TCP/IP是个协议组,它分为三个层次:网络层.传输层和应用层: 网络层包括:IP协议.ICMP协议.ARP协议.RARP协议和BOOTP协议. 传输层包括:TCP协议.UDP协议. 应用层包括:HT

Android基础入门教程——7.6.3 基于TCP协议的Socket通信(2)

Android基础入门教程--7.6.3 基于TCP协议的Socket通信(2) 标签(空格分隔): Android基础入门教程 本节引言: 上节中我们给大家接触了Socket的一些基本概念以及使用方法,然后写了一个小猪简易聊天室的 Demo,相信大家对Socket有了初步的掌握,本节我们来学习下使用Socket来实现大文件的断点续传! 这里讲解的是别人写好的一个Socket上传大文件的例子,不要求我们自己可以写出来,需要的时候会用 就好! 1.运行效果图: 1.先把我们编写好的Socket服务