工具的準備:
編寫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