在Android上使用Socket


原文地址:http://www.cnblogs.com/kross/p/3621952.html

 

考慮到以后可能要用到這方面的知識,就來寫個Demo嘗試下,其實以前學過,但不記得了……(用不到的東西各種不記得啊)

直接進入正題吧,在Android上使用Socket實際上跟在Java中使用差不多,只要注意下在Manifest中加網絡權限就好了(我原來經常犯這個錯誤),另外網絡請求不能再主線程里,基本就OK了。

そして,先寫一個服務器的小程序吧。就直接使用Java寫就好了,灰常的簡單,隨便寫寫。

/**
 * 測試服務器
 * */
public class TestServer {

    public static void main(String[] args) throws IOException {
        
        ServerSocket ss = new ServerSocket(5417);
        
        Socket client = null;
        
        while (true) {
            System.out.println("waiting for...");
            client = ss.accept();
            BufferedReader br = new BufferedReader(new InputStreamReader(client.getInputStream()));
            System.out.println(br.readLine());
        }
    }
}

然后我的構想是,手機上有一個輸入框,一個按鈕,用戶可以按按鈕,把輸入框里的內容發送到服務器上。一開始我寫了一個很混亂的demo,為了更加方便使用,就把Socket的封裝了一下,就叫SocketManager吧,代碼如下:

/**
 * SocketManager,簡單的封裝了一下
 * @author Kross(krossford@foxmail.com)
 * @date 2014-3-24 21:39:48
 * */
public class SocketManager {
    
    private Socket client = null;
    
    //服務器的IP地址
    private String ip = "113.251.172.30";
    
    //監聽的端口號
    private int port = 5417;
    
    /**
     * 獲取一個實例
     * */
    public static SocketManager newInstance() throws UnknownHostException, IOException {
        return new SocketManager();
    }
    
    private SocketManager() throws UnknownHostException, IOException {
        client = new Socket(ip, port);
    }
    
    /**
     * 發送一條消息
     * @param msg 消息內容
     * */
    public void sendMessage(String msg) throws IOException {
        PrintWriter printWriter = new PrintWriter(client.getOutputStream());
        printWriter.print(msg);
        printWriter.flush();
        printWriter.close();    //一定要關閉輸出流,要不然消息無法送達到服務器
    }
}

幾個要點:

1.IP地址就寫Java程序鎖運行的機器的公網地址,cmd->ipconfig就可以查到。

2.端口號請和服務器那個保持一致,都不在一個管道里怎么通信哇。

3.我使用了靜態工廠方法,每次都要重新new一個SocketManager,因為我發現Socket這個類只能用一次,close之后再發送便沒用了。

4.服務器要收到信息,必須要客戶端的東西close了,輸出流close也好,socket.close也好,總之要close,服務器才能確切的收到。

然后,我寫了一個線程來執行這個Socket,因為不能在主線程跑嘛,我想了很久,可不可以讓這個線程一直執行着,然后只要調用下這個線程的sendMessage方法,就可以發送了,這樣就只需要new一個線程就行了,但是我想了好久,都想不通,貌似不能那樣,線程要么沒有,有的話就會一股腦的執行它的run()方法,想要長時間持有它?在run里面加個while(true)?那怎么做到調用它的共有方法呢?總之,我沒有想到用只需要new一個線程就可以發N個請求的辦法,貌似需要使用到Service來實現了。

/**
 * 發起請求的線程
 * @author Kross(krossford@foxmail.com)
 * @date 2014-3-24 21:40:21
 * */
public class SocketThread implements Runnable {
    
    private String message;
    
    public SocketThread(String msg) {
        message = msg;
    }
    
    @Override
    public void run() {
        try {
            SocketManager.newInstance().sendMessage(message);
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

這里倒沒什么好說的。接下來我們就直接在MainActivity里面准備好控件,監聽器,然后就OK了,大致的看下代碼吧。

public class MainActivity extends Activity {
    
    private EditText etInput = null;
    private Button bSend = null;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        Log.i("MainActivity", Thread.currentThread().getName());
        
        etInput = (EditText)findViewById(R.id.et_input);
        bSend = (Button)findViewById(R.id.b_send);
        
        bSend.setOnClickListener(new SendButtonListener());
        
    }
    
    class SendButtonListener implements OnClickListener {

        @Override
        public void onClick(View v) {
            String msg = etInput.getEditableText().toString().trim();
            new Thread(new SocketThread(msg)).start();
            etInput.setText("");
        }
    }
}

OK,代碼就是這樣了,來看下最終的運行效果吧。

先啟動Java的服務器程序,啟動后結果是這樣的:

然后我們運行手機上的程序,發送一條消息:

再來看服務器端的程序:

看上去一切正常,再來一發!

再看看服務器的程序:

OK,看來是沒有問題了。

 

服務器如何向Socket返回信息暫時還沒有去實驗,留着明天來搞吧……

 

原文地址:http://www.cnblogs.com/kross/p/3621952.html

新浪微博:http://weibo.com/KrossFord


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM