Android手机 (客户端)和PCweb 端(服务端)的socket通信

原创 2013年12月06日 15:15:18

实例:手机端登录,把登录名和密码发送到服务端,服务端在接收到用户名密码之后返回一个”ok”给客户端,客户端进行打印/判断

手机客户端代码:

package com.example.registerlogin;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;

public class MainActivity extends Activity implements OnClickListener {

	private String url = "192.168.111.111";// ip地址,这里是指服务端所在的机器的ip地址
	private int port = 8008;// 端口号,不要写你本机其他 程序已经占用的端口号,其他随便取,这个端口号也是服务端需要监听的端口号

	private EditText usernameET, passwordET;// 输入用户名和密码
	private Button registerBT, loginBT;// 注册和登录按钮
	private String username, password;
	private Socket socket;
	private PrintWriter printWriter; //写
	private BufferedReader bufR;//读

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

		usernameET = (EditText) findViewById(R.id.usernameET);
		passwordET = (EditText) findViewById(R.id.passwordET);
		savePassCB = (CheckBox) findViewById(R.id.savePassCB);
		autoLoginCB = (CheckBox) findViewById(R.id.autoLoginCB);
		registerBT = (Button) findViewById(R.id.registerBT);
		loginBT = (Button) findViewById(R.id.loginBT);

		registerBT.setOnClickListener(this);
		loginBT.setOnClickListener(this);

	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.registerBT:
			Intent intent = new Intent();
			intent.setClass(MainActivity.this, RegisterActivity.class);
			startActivity(intent);
			break;
		case R.id.loginBT:
			// 这里需要开启另一个线程,因为联网操作是一个耗时的操作,如果在主线程中联网容易造成activity的假死现象
			new Thread(new LoginThread()).start();
			System.out.println("username : ---------" + username);
			System.out.println("password : ==============" + password);
			break;
		}
	}

	class LoginThread implements Runnable {
		@Override
		public void run() {
			try {
				socket = new Socket(url, port);//new socket对象,指定ip和端口号
				printWriter = new PrintWriter(socket.getOutputStream(), true);//建议使用这个类进行写, readLine()和read()是一个阻塞式方法,readLine()如果没有读到换行,则一直在等待不会终止,read() 是读到-1,所以选择缓冲流读取的话,则printWriter能够在末尾写入换行让读取到一行的时候能够停止。当然也可以只读一行,但是如果没有读到换行符,readLine()同样会阻塞在那里,这时候就需要在写(源)的时候自己写上换行符。true:自动刷新。使用缓冲流写的时候也需要刷新。
				bufR = new BufferedReader(new InputStreamReader(
						socket.getInputStream()));

				String logic = "<LOGIC>"; //给登录信息加上头部,让客户端接收的时候能够判断是登录还是注册
				username = usernameET.getText().toString();
				password = passwordET.getText().toString();

				String msgOut = logic + username + "|" + password;
				printWriter.println(msgOut);//写数据,并且带上了换行符

				String line = null;
				while((line = bufR.readLine()) != null){
					System.out.println(line);
					if ("ok".equals(line)) {
						// 登录成功
						System.out.println("登录成功");
					}
				}

			} catch (UnknownHostException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				try {
					if (bufR != null)
						bufR.close();
				} catch (IOException e1) {
					e1.printStackTrace();
				}
				try {
					socket.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}
}

web服务端代码:

新建一个web工程。首先得在配置文件中监听一个端口号(即客户端指定的端口号),并指定一个监听类。

web.xml

<context-param>
<param-name>socketPort</param-name>
<param-value>8008</param-value>
</context-param>
<listener>
		<description>Socket 服务随web 启动而启动</description>
		<listener-class>com.bafengte.ServerSocketListener</listener-class>
	</listener>


在web工程src下新建一个ServerSocketListener类:

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class ServerSocketListener implements ServletContextListener {
	private SocketThread socketThread;

	public void contextDestroyed(ServletContextEvent e) {//当Servlet 容器终止Web 应用时调用该方法
		// TODO Auto-generated method stub
		if (socketThread != null && !socketThread.isInterrupted()) {
			socketThread.closeServerSocket();
			socketThread.interrupt();
		}
	}

	public void contextInitialized(ServletContextEvent e) {//当Servlet 容器启动Web 应用时调用该方法。
		// TODO Auto-generated method stub
		ServletContext servletContext = e.getServletContext();
		if (socketThread == null) {
			socketThread = new SocketThread(servletContext, null);
			socketThread.start(); // servlet上下文初始化时启动socket服务端线程
		}
	}
}

在web工程src下新建一个SocketThread类:

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import javax.servlet.ServletContext;

public class SocketThread extends Thread {
	private ServletContext servletContext;
	private ServerSocket serverSocket;

	public SocketThread(ServletContext servletContext, ServerSocket serverSocket) {
		this.servletContext = servletContext;
		// 从web.xml中context-param节点获取socket端口
		String port = this.servletContext.getInitParameter("socketPort");
		if (serverSocket == null) {
			try {
				this.serverSocket = new ServerSocket(port);//服务器端核心代码1
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	public void run() {
		while (!this.isInterrupted()) { // 线程未中断执行循环
			try {
				Socket socket = serverSocket.accept();//服务器端核心代码2
				if (socket != null)
					new ProcessSocketData(socket, this.servletContext).start();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	public void closeServerSocket() {
		try {
			if (serverSocket != null && !serverSocket.isClosed())
				serverSocket.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

在web工程src下新建一个ProcessSocketData类:

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

import javax.servlet.ServletContext;

public class ProcessSocketData extends Thread {
	private Socket socket;
	private ServletContext servletContext;

	public ProcessSocketData() {
		super();
	}

	public ProcessSocketData(Socket socket, ServletContext servletContext) {
		this.socket = socket;
		this.servletContext = servletContext;
	}

	public void run() {
		try {
			BufferedReader br = new BufferedReader(new InputStreamReader(socket
					.getInputStream()));//服务器端核心代码,以下都是
			PrintWriter printWriter = new PrintWriter(socket.getOutputStream(),true);
			
			String line = null;
			while((line = br.readLine()) != null){
				System.out.println("接收到的数据 ------" + line);
				printWriter.println("ok");
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}




版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

实现Android手机(服务端)与PC(客户端)实现通信

本文在此基础上做了一些修改:http://blog.csdn.net/wufenglong/article/details/5778862   我主要是要通过在PC端发送命令控制手机作出相应的反应,...

Android手机客户端通过JSP实现与Tomcat服务器端通信(Msql数据库,Json作为载体)--服务端代码

服务器端主要代码: 1.首先构建一个Person类,用来保存用户信息 public class Person private String name; private String ad...

Android实现FTP客户端服务端多图下载【两部android手机之间传输】

一、背景介绍 关于FTP下载,FTP是File Transfer Protocol(文件传输协议)的英文简称,而中文简称为“文传协议”。用于Internet上的控制文件的双向传输。同时,它也是一个应...
  • tyyj90
  • tyyj90
  • 2015-09-13 19:47
  • 2358

安卓手机socket通信(服务端和客户端)

socket通信
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)