读书人

一步一步android(15):关于socket编程

发布时间: 2012-08-21 13:00:21 作者: rapoo

一步一步android(15):关于socket编程【以聊天为例】[转]

http://hi.baidu.com/gk14/blog/item/a25c0e463fbc1a056a63e52c.html

?

Android手机的应用,除了它的手机功能之外,另外一个吸引人的地方在于它的开放性,这一点iphone无法比拟,至少iphone太多商业化气息。

如同当年windows95一样,android为我们开启另一扇交流之窗,而要实现交流,socket通信必不可少。

java在socket通信方面上已经有了很好的范例,我只是抛砖引玉,将其引入到android之中,疏漏之处在所难免,很多地方也值得深思与考量,高手不必拍砖,可跳过此文。

下面,用敲门的方式演示Android如何实现套接字的通信。

本例实现功能如下:

Server端开启服务
Client端发起链接请求,并向Server端发送数据
Server端响应请求,并在Server显示,向Client端返回数据
Client端接收Server的数据并显示

本例效果如下:

终端1:


终端2:

?

Server端:


本例源代码如下:

Server端:

package com.android.Yao;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class YaoChatServer extends Thread {

private YaoChatServer() throws IOException {
?? CreateSocket();
?? //创建Socket服务器
}

public void run() {?
?? Socket client;
?? String txt;
?? try {?
??? while (true)
??? //线程无限循环,实时监听socket端口
??? {
???? client=ResponseSocket();???????
???? //响应客户端链接请求。。
????
???? while(true)
???? {
????? txt=ReceiveMsg(client);??
????? System.out.println(txt);
????? //链接获得客户端发来消息,并将其显示在Server端的屏幕上
???
????? SendMsg(client,txt);
????? //向客户端返回消息

????? if(true)break;
????? //中断,继续等待链接请求
???? }
????
???? CloseSocket(client);
???? //关闭此次链接
??? }???
?? }?
?? catch (IOException e) {
??? System.out.println(e);
?? }

}

private ServerSocket server = null;
private static final int PORT = 5000;
private BufferedWriter writer;
private BufferedReader reader;

private void CreateSocket() throws IOException
{
?? server = new ServerSocket(PORT, 100);
?? System.out.println("Server starting..");??
}

private Socket ResponseSocket() throws IOException
{
?? Socket client = server.accept();?
?? System.out.println("client connected..");
??
?? return client;
}

private void CloseSocket(Socket socket) throws IOException
{
?? reader.close();
?? writer.close();
?? socket.close();
?? System.out.println("client closed..");
}

private void SendMsg(Socket socket,String Msg) throws IOException?
{
?? writer = new BufferedWriter(
????? new OutputStreamWriter(socket.getOutputStream()));
??? writer.write(Msg+"\n");
??? writer.flush();
???
}

private String ReceiveMsg(Socket socket) throws IOException
{
?? reader = new BufferedReader(
???? new InputStreamReader(socket.getInputStream()));?????
??? System.out.println("server get input from client socket..");
??? String txt="Sever send:"+reader.readLine();
???
??? return txt;
}

public static void main(final String args[]) throws IOException {
?? YaoChatServer yaochatserver = new YaoChatServer();
?? if (yaochatserver != null) {
??? yaochatserver.start();
?? }
}

}

?

Client端:

package com.android.Yao;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.net.UnknownHostException;

import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.*;


public class YaoChatRoomAndroid extends Activity {
??? /** Called when the activity is first created. */
??? @Override
??? public void onCreate(Bundle savedInstanceState) {
??????? super.onCreate(savedInstanceState);
??????? setContentView(R.layout.chatroom);
???????

??????? findviews();
??????? setonclick();

??? }

??? private EditText chattxt;
??? private TextView chattxt2;
??? private Button chatok;
????
??? public void findviews()
??? {
??????? chattxt = (EditText)this.findViewById(R.id.chattxt);
??????? chattxt2 = (TextView)this.findViewById(R.id.chattxt2);
??????? chatok?? = (Button)this.findViewById(R.id.chatOk);
??? }
????
??? private void setonclick()
??? {
??????? chatok.setOnClickListener(new View.OnClickListener() {
???
??? @Override
??? public void onClick(View v) {
???? try {
????? connecttoserver(chattxt.getText().toString());
???? } catch (UnknownHostException e) {
????? // TODO Auto-generated catch block
????? e.printStackTrace();
???? } catch (IOException e) {
????? // TODO Auto-generated catch block
????? e.printStackTrace();
???? }
??? }
?? });
??? }


??? public void connecttoserver(String socketData) throws UnknownHostException, IOException
{
??? Socket socket=RequestSocket("192.168.0.107",5000);
?? SendMsg(socket,socketData);??
?? String txt = ReceiveMsg(socket);
?? this.chattxt2.setText(txt); ???
}

????
??? private Socket RequestSocket(String host,int port) throws UnknownHostException, IOException
??? {???
??? Socket socket = new Socket(host, port);
??? return socket;
??? }
????
??? private void SendMsg(Socket socket,String msg) throws IOException
??? {
??? BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
?? writer.write(msg.replace("\n", " ")+"\n");
?? writer.flush();
??? }
????
??? private String ReceiveMsg(Socket socket) throws IOException
??? {
??? BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
????
?? String txt=reader.readLine();
?? return txt;

??? }????
}

?

20. } catch(Exception e) {
21. System.out.println("S: Error");
22. e.printStackTrace();
23. } finally {
24. client.close();
25. System.out.println("S: Done.");
26. }
27.

28. }
29.

30. } catch (Exception e) {
31. System.out.println("S: Error");
32. e.printStackTrace();
33. }
34. }
35.

36. public static void main (String a[]) {
37. Thread desktopServerThread = new Thread(new TCPDesktopServer());
38. desktopServerThread.start();
39. }
40.}


对上边的源代码做一些介绍:
指定Server监听的端口和服务器IP地址。
1.public static final String SERVERIP = "192.168.0.149";
2.public static final int SERVERPORT = 51706;


应用之前所指定的IP和Port创建一个ServerSocket对象。
1.ServerSocket serverSocket = new ServerSocket(SERVERPORT);


用于侦听和捕捉通过Socket连接的客户端。
1.Socket client = serverSocket.accept();


应用Socket创建BufferedReader对象,用于接收Socket Stream中的数据。
1.BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));


Android Client 源代码:
01.InetAddress serverAddr = InetAddress.getByName("192.168.0.149");//TCPServer.SERVERIP
02.Log.d("TCP", "C: Connecting...");
03.Socket socket = new Socket(serverAddr, 51706);
04.String message = "AndroidRes,Where is my Pig (Android)?";
05.try {
06. Log.d("TCP", "C: Sending: '" + message + "'");
07. PrintWriter out = new PrintWriter( new BufferedWriter( new OutputStreamWriter(socket.getOutputStream())),true);
08. out.println(message);
09.} catch(Exception e) {
10. Log.e("TCP", "S: Error", e);
11.} finally {
12. socket.close();
13.}


对上边的源代码做一些介绍:
指定Server的IP地址。
1.InetAddress serverAddr = InetAddress.getByName("192.168.0.149");


应用Server的IP和端口建立Socket对象。
1.Socket socket = new Socket(serverAddr, 51706);


根据已经建立的Socket来创建PrintWriter,将信息通过这个对象来发送给Server,其中包含了三个部分:
OutputStreamWriter
BufferedWriter
PrintWriter
1.PrintWriter out = new PrintWriter( new BufferedWriter( new OutputStreamWriter(socket.getOutputStream())),true);


以上是Android与运行在PC上的Java Server通讯的例子。来源由Anddev.org提供
2. Android与PC通讯的第二个例子:
PC: CSharp Server
Android:Java Client

通过上边的例子,本人通过一些转换,实现了Android与CSharp Server的通讯方法。原理没有太大差异,仅仅是应用的方法稍有不同。
CSharp Server 源代码:
01.TcpClient ConnectedClient = ServerListener.AcceptTcpClient();
02.

03.NetworkStream netStream = ConnectedClient.GetStream();
04.

05.BinaryReader br = new BinaryReader(netStream);
06.

07.byte[] tempByte = new byte[8192];
08.

09.tempByte = br.ReadBytes(8192);
10.

11.string RecevieString = System.Text.Encoding.Default.GetString(tempByte);


对上边的源代码做一些介绍:
通过TcpListener获得的Client信息创建一个TcpClient对象。
1.TcpClient ConnectedClient = ServerListener.AcceptTcpClient();


从TcpClient对象中提取NetworkStream对象,其目的是建立Socket数据流。
1.NetworkStream netStream = ConnectedClient.GetStream();


建立BinaryReader对象为刚刚创建的NetworkStream提供一个接口,借助于这个接口可以非常方便的读取信息。
1.BinaryReader br = new BinaryReader(netStream);


读取Stream中的byte array数据,转化为string字符串。
1.byte[] tempByte = new byte[8192];
2.

3.tempByte = br.ReadBytes(8192);
4.

5.string RecevieString = System.Text.Encoding.Default.GetString(tempByte);


Android Client 源代码:
这个Android Client所应用的方法与第一个例子中有很大区别,请各位特别注意(通过本人的反复验证,这个算是Java 与CSharp间可行的通讯方法)。
1.String message = "AndroidRes,Where is my Pig (Android)?";
2.Socket socket = new Socket("192.168.0.149", 51706);
3.OutputStream ops=socket.getOutputStream();
4.DataOutputStream dos=new DataOutputStream(ops);
5.dos.write(message.getBytes());
6.dos.close();


对上边的源代码做一些介绍:
同样是建立Socket对象。
1.Socket socket = new Socket("192.168.0.149", 51706);


根据Socket对象创建OutputStream对象,根据名称可以很容易的理解这个对象的目的,它是建立一个输出的NetworkStream。
1.OutputStream ops=socket.getOutputStream();


DataOutputStream类似于BinaryWriter,是为OutputStream建立一个接口,可以通过这个接口向Socket另外一端写数据。
1.DataOutputStream dos=new DataOutputStream(ops);


最后这两行代码是实施写的过程。
1.dos.write(message.getBytes());
2.dos.close();


以上就是本站为大家提供的两种Android与PC间通讯的方式(其中第一个方法来自Anddev.org,这里要特别指出)。如果你有更巧妙或者更方便的方法,希望能与大家共同分享!13.

14. // sendfile
15. File myFile = new File ("source.pdf");
16. byte [] mybytearray = new byte [(int)myFile.length()];
17. FileInputStream fis = new FileInputStream(myFile);
18. BufferedInputStream bis = new BufferedInputStream(fis);
19. bis.read(mybytearray,0,mybytearray.length);
20. OutputStream os = sock.getOutputStream();
21. System.out.println("Sending...");
22. os.write(mybytearray,0,mybytearray.length);
23. os.flush();
24. sock.close();
25. }
26. }
27.}


客户端源代码:
01.import java.net.*;
02.import java.io.*;
03.

04.public class FileClient{
05. public static void main (String [] args ) throws IOException {
06. int filesize=6022386; // filesize temporary hardcoded
07.

08. long start = System.currentTimeMillis();
09. int bytesRead;
10. int current = 0;
11. // localhost for testing
12. Socket sock = new Socket("127.0.0.1",13267);
13. System.out.println("Connecting...");
14.

15. // receive file
16. byte [] mybytearray = new byte [filesize];
17. InputStream is = sock.getInputStream();
18. FileOutputStream fos = new FileOutputStream("source-copy.pdf");
19. BufferedOutputStream bos = new BufferedOutputStream(fos);
20. bytesRead = is.read(mybytearray,0,mybytearray.length);
21. current = bytesRead;
22.

23. // thanks to A. Cádiz for the bug fix
24. do {
25. bytesRead =
26. is.read(mybytearray, current, (mybytearray.length-current));
27. if(bytesRead >= 0) current += bytesRead;
28. } while(bytesRead > -1);
29.

30. bos.write(mybytearray, 0 , current);
31. bos.flush();
32. long end = System.currentTimeMillis();
33. System.out.println(end-start);
34. bos.close();
35. sock.close();
36. }
37.}

读书人网 >编程

热点推荐