您的位置:首页 > 移动开发 > Android开发

android socket通信

2011-12-15 15:57 183 查看
通信环境:

客户端:android手机 模拟器。采用sdk 6      , myEclipse8.5

服务端:pc电脑,采用控制台应用程序  , myEclipse9.1

 

socket通信是一种通讯协议,适用于c/s结构的应用程序,与编写的android应用程序刚好符合,今天编写一下android与pc机之间借助与socket协议来通讯的应用程序,目的是为了温习java.net包下一些类的使用方法。

此程序我在模拟器与真机上均测试成功,请注意,在使用真机测试时,需要有网络接入点,并且服务端需要和客户端在同一网段,假如电脑与手机都接入同一路由器共享上网,则可以实现通信。

 

服务端:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.Enumeration;

public class Server {

//监听器对象
private ServerSocket server;

/**
* 实例化,指定监端口
* @param port
*/
public Server(int port)
{
try {

//指定监听端口和最大访问数量
server = new ServerSocket(port, 10);

} catch (IOException e) {
e.printStackTrace();
}
}

/**
* 获取本机ip地址
*/
public String getLocalAddress(){

try {
//获取所有可用网络接口
Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();

while (networkInterfaces.hasMoreElements()) {

NetworkInterface networkInterface = (NetworkInterface)networkInterfaces.nextElement();
//获取接口内可用的地址信息
Enumeration<InetAddress> inetAddresses = networkInterface.getInetAddresses();

while (inetAddresses.hasMoreElements()) {

InetAddress inetAddress = (InetAddress) inetAddresses.nextElement();

//判断不为本地回环地址 , 及不为127.0.0.1
if(!inetAddress.isLoopbackAddress())
{
System.out.println(inetAddress.getHostName());
System.out.println(inetAddress.getHostAddress());
return inetAddress.getHostAddress();
}
}
}
} catch (SocketException e) {

e.printStackTrace();
}

//如果找不到地址,就用回环地址
return "127.0.0.1";
}

public void Listener()
{

while(true)
{
try {

System.out.println("开始监听 ----- 等待数据");
//开始监听,等待数据的到来
final Socket socket = server.accept();

//新的线程
new Thread( new Runnable() {
public void run() {

//缓冲器
BufferedReader in;

try {
in = new BufferedReader(new InputStreamReader(socket.getInputStream() , "UTF-8"));

while(!socket.isClosed()){
String str;
str = in.readLine();
if(str == null)
break;
System.out.println(str);
}
System.out.println("--------------------");
socket.close();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

}
}).start();

} catch (IOException e) {
e.printStackTrace();
}
}

}

/**
* 入口
* @param args
*/
public static void main(String[] args) {

//设置9758为服务器监听端口
new Server(9758).Listener();

}

}

 

 

其中有一个方法getLocalAddress() ,是为了获取本地网卡ip地址,在.net 中如果要使用监听则需要获取本地ip地址,java中则不用,所以此方法暂时得不到使用

值得注意的是,代码中以9758为监听端口,0-1024为系统端口,一般自定义端口不要在此范围内,一般的端口定义可以在1025  - 60000(多) , 在此范围内可以自己选择,

但是要注意,有些程序的端口会和本应用冲突,所以要避开,例如sqlserver 2005 ,端口号: 1433 ,  oracle端口号 1521。

 

 

以下代码为客户端: activity

package com.lee.activity;

import com.lee.socket.ClientSocket;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

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

final EditText text = (EditText)this.findViewById(R.id.txtEdit);

final Button button = (Button)this.findViewById(R.id.btnSend);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ClientSocket socket = new ClientSocket();
String str = text.getText().toString();
socket.send(str);
socket.close();
}
});

}
}


下面为socket发送

 

package com.lee.socket;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
import java.net.UnknownHostException;

public class ClientSocket{

private Socket socket;
private final static String IPADDRESS = "192.168.0.101";
private final static int PORT = 9758;

public ClientSocket()
{
super();
if(socket == null)
{
try {
socket = new Socket(IPADDRESS, PORT);
System.out.println("连接建立成功: ip:"+ IPADDRESS +" port:"+PORT);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}

public void send(String msg)
{
try {
PrintWriter out = new PrintWriter(socket.getOutputStream());
out.println(msg);
out.flush();

} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}

public synchronized void close()
{
try {
socket.close();
socket = null;
} catch (IOException e) {
e.printStackTrace();
}
}

}


 

 



 

最后,我们在manifest.xml文件中添加以下权限,以便android应用程序能够正常访问网络

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>

<uses-permission android:name="android.permission.INTERNET"></uses-permission>

 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息