工具的准备:
编写Web服务端的代码:IDEA
编写Android客户端的代码: Android Studio
web服务端的部署工具:Tomcat 7.0.82
代码清单:
客户端:
package com.example.administrator.filetransportapp;
import android.app.Activity;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
public class MainActivity extends Activity {
String IP="175.0.152.169";
int PORT=8000;
EditText et_message;
TextView tv_result;
StringBuffer stringBuffer=new StringBuffer();
String message;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Init();
}
public void Init(){
et_message= (EditText) findViewById(R.id.message);
tv_result= (TextView) findViewById(R.id.tv_result);
}
public void SendMessage(View v){
Send();
}
public void Send(){
Thread th=new Thread(new Runnable() {
@Override
public void run() {
try {
Socket socket=new Socket(IP,PORT);
if(socket.isConnected()){
System.out.println("连接主机成功");
}else{
System.out.println("连接主机失败");
}
OutputStreamWriter osw = new OutputStreamWriter(socket.getOutputStream(), "UTF-8");
/* 客户端向服务器发送数据 */
PrintWriter pw
= new PrintWriter(osw, true);
pw.println(et_message.getText().toString());
/* 客户端接收服务器数据 */
InputStreamReader isr = new InputStreamReader(socket.getInputStream(), "UTF-8");
BufferedReader br = new BufferedReader(isr);
String msgReceive = null;
while(true) {
if((msgReceive = br.readLine()) != null) {
stringBuffer.append(msgReceive);
runOnUiThread(new Runnable() {
@Override
public void run() {
tv_result.setText("\n"+stringBuffer.toString());
}
});
System.out.println("服务器说:" + msgReceive);
}
}
} catch (IOException e) {
System.out.println("\nSocket的连接失败");
e.printStackTrace();
}
}
});
th.start();
}
}
服务端代码清单【一共三个文件】:
1.ServerSocketThread类:
import java.io.*;
import java.net.Socket;
/**
* <p>
* Socket线程服务类
* <p>
*
*/
public class ServerSocketThread extends Thread {
private Socket socket;
public ServerSocketThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
InputStream is = null;
InputStreamReader isr = null;
BufferedReader br = null;
OutputStream os = null;
PrintWriter pw = null;
try {
// socket获取字节输入流
is = socket.getInputStream();
// 将字节输入流转字符输入流
isr = new InputStreamReader(socket.getInputStream(), "UTF-8");
// 将字符输入流转行输入流
br = new BufferedReader(isr);
String message = null;
if ((message = br.readLine()) != null) {
System.out.println("客户端发来消息:" + message+socket.getRemoteSocketAddress());
}
// 必须先关闭输入流才能获取下面的输出流
socket.shutdownInput();
String msgSend = "\nhello I am server, I have receive your message: "+message;
/* 服务器向客户端发送数据 */
OutputStreamWriter osw = null;
osw = new OutputStreamWriter(socket.getOutputStream(), "UTF-8");
pw = new PrintWriter(osw, true);
pw.println(msgSend);
pw.flush();
System.out.println("向客户端发送"+msgSend);
} catch (Exception e) {
e.printStackTrace();
} finally {
// 关闭输入流
try {
socket.shutdownOutput();
} catch (IOException e) {
e.printStackTrace();
}
// 收工前最后一步:关闭资源
try {
if (pw != null) {
pw.close();
}
if (br != null) {
br.close();
}
if (isr != null) {
isr.close();
}
if (os != null) {
os.close();
}
if (br != null) {
br.close();
}
if (isr != null) {
isr.close();
}
if (is != null) {
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
2.Server类:
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
/**
* <p>
* 基于socket通讯-服务端
*/
public class Server {
private static ServerSocket SERVER_SOCKET =null;;
static{
try {
SERVER_SOCKET = new ServerSocket(8000);
} catch (IOException e) {
System.out.println("\n端口已被占用");
e.printStackTrace();
}
}
public void start(){
try {
System.out.println("-----服务器已启动,等待客户端连接----");
Socket socket = null;
while(true){
//循环监听客户端的连接
socket = SERVER_SOCKET.accept();
//新建一个线程ServerSocket,并开启
new ServerSocketThread(socket).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
try {
System.out.println("-------服务器已启动,等待客户端连接----");
Socket socket = null;
while(true){
//循环监听客户端的连接
socket = SERVER_SOCKET.accept();
//新建一个线程ServerSocket,并开启
new ServerSocketThread(socket).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
3.ServerListener
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class ServerListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
Thread thread=new Thread(new Runnable() {
@Override
public void run() {
Server server=new Server();
server.start();
}
});
thread.start();
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
}
}
最后就是运行效果了:
第一步:启动服务端
第二步:打开Android虚拟机,发送消息
服务台的打印台输出:
再用真机发送一句中文:
[虚拟机那边,手抖,多按了一次发送,所以是发送了两次good job]
好的,现在,代码和效果已经展示完毕。
接下来记录一下我在编写代码时遇见过的问题以及解决方法:
问题一:做内网测试时,我的服务器所在的台式电脑与我的真机不在同一个内网,测试失败,怎么办?
解决方法一:用虚拟机做测试,因为电脑的虚拟机和台式电脑肯定是在同一个内网。
解决方法二:用外网映射,具体操作看下图:
第一步:查询本机的IP,win+R,打开cmd,输入:ipconfig查询到我的本机IP是:192.168.1.102
第二步:设置外网映射,打开浏览器,在地址栏输入:192.168.1.1 然后账号密码都是:admin
在网页的左侧,点击转发规则,在后面添加一个IP和Port:
第3步:查看电脑主机的外网IP地址
点击网页左侧的运行状态:
第四步:编写代码
服务端的Socket监听端口,将端口改为映射的端口,我的是8000.
在客户端Socket连接的IP改为服务器外网的IP,端口设置为8000,与上面的保持一致。
问题二:如何给web服务器添加监听?
这个问题,对各位读者可能没有普遍的借鉴意义,我就当是做个总结啦。
首先,要写好Socket的Server,其次是编写一个继承了ServerletContextListener的类,并在web.xml进行注册:
最重要的,差点忘记了,感谢以下两位博主的分享,让我可以学习,非常感谢~附上链接,有需要的读者可以点击进去查看
http://www.cnblogs.com/forget406/p/5336748.html
http://www.cnblogs.com/parryyang/p/6282563.html