欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android实现TCP与UDP传输

程序员文章站 2024-02-11 09:22:10
...

 

关于TCPUDP协议的描述,可参考http://zhoujianghai.iteye.com/blog/1052970

 

下面是androidPC端使用TCPUDP协议通信的例子:

PC端作为服务器,android端使用TCP协议与服务器建立连接,使用UDP协议接受和发送数据。

服务器端代码:

ThunderServer.java

 

package com.zhoujh.thunder.server;

import java.io.DataOutputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.ArrayList;

/**
 * 服务器端
 * @author 
 * zhoujianghai
 * 2011-5-15
 * 下午05:10:50
 */
public class ThunderServer{
	private static int ID = 1;
	
	/**TCP端口 */
	private static final int TCP_PORT = 8000;
	/**UDP端口 */
	private static final int UDP_PORT = 9999;
	
	
	/**与服务器已经建立链接的客户端数量 */
	private ArrayList<Client> clients = new ArrayList<Client>();
	
	public static void main(String args[]) {
		new ThunderServer().start();
	}

	private void start() {
		new UDPThread().start();
		ServerSocket serverSocket = null;

		try {
			serverSocket = new ServerSocket(TCP_PORT);
		} catch (IOException e) {
			e.printStackTrace();
		}
		while (true) {
			Socket socket = null;
			try {
				socket = serverSocket.accept();
				System.out.println("socket="+socket);
				
			
				String IP = socket.getInetAddress().getHostAddress();
				Client c = new Client(IP);	
				clients.add(c);
				
				DataOutputStream out = new DataOutputStream(socket.getOutputStream());
				out.writeInt(ID++);
				
				System.out.println("一个新的客户端已连接,IP:"+IP+";port="+socket.getPort()+"; ID="+(ID-1));
			} catch (IOException e) {
				e.printStackTrace();
			}finally{
				if(socket != null) {
					try {
						socket.close();
						socket = null;
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		}
		
	}
	
	/**
	 * 客户端:ip地址和udp端口
	 * @author 
	 * zhoujianghai
	 * 2011-5-15
	 * 下午04:41:09
	 */
	private class Client {
		String IP;
		int udpPort;

		public Client(String IP) {
			this.IP = IP;
		}
		public void setUdpPort(int udpPort) {
			this.udpPort = udpPort;
		}
	}
	
	/**
	 * 接收客户端发送的数据,并把接收到的数据发送给所有客户端,使用UDP协议
	 * @author 
	 * zhoujianghai
	 * 2011-5-15
	 * 下午04:54:03
	 */
	private class UDPThread extends Thread {
		//服务器每次收发数据的缓冲区,大小是1024个字节
		byte[] buf = new byte[1024];
		
		public void run() {
			DatagramSocket ds = null;
			try {
				ds = new DatagramSocket(UDP_PORT);
			} catch (SocketException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			while(ds != null) {
				DatagramPacket packet = new DatagramPacket(buf, buf.length);

				try {
					//接收数据包
					ds.receive(packet);
					System.out.println("地址:"+packet.getAddress()+"  端口:"+packet.getPort()+"数据:"+new String(packet.getData()));
					String clientIp =  (packet.getAddress().toString().split("/")[1]);
					for(Client c:clients) {
						
						if(clientIp.trim().equals(c.IP) && c.udpPort == 0) {
							c.setUdpPort(packet.getPort());
						}
					}
					//把接收到的数据包发送给所有已连接的客户端
					System.out.println("clients.size="+clients.size());
					for(Client c:clients) {
						System.out.println("server send:IP="+c.IP+"; udpPort="+c.udpPort);
						//设置数据包要发送的客户端地址
						packet.setSocketAddress(new InetSocketAddress(c.IP, c.udpPort));
						ds.send(packet);
					}
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
}
 

客户端的核心代码:

 

public void connectServer(String IP,int port) {

		this.IP = IP;
		
		try {
			socket = new DatagramSocket(udpPort);
		} catch (SocketException e) {
			e.printStackTrace();
		}
		
		Socket s = null;
		try {
			s = new Socket(IP,port);
			System.out.println("s="+s);
			
			DataInputStream dis = new DataInputStream(s.getInputStream());
			int id = dis.readInt();
			System.out.println("id="+id);
	
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			if(s != null) {
				try {
					s.close();
					s = null;
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	
	}
 

 

客户端代码绑定的UDP端口”udpPort“跟服务器端接收到的不一样,为了避免了使用UDP通信时,android客户端接收不到server发送的数据的问题,server端根据接收到的数据得出发送数据包的客户端的ip地址和端口,不需要进行端口的转发,真机和模拟器一样。代码:

 

String clientIp =  (packet.getAddress().toString().split("/")[1]);
					for(Client c:clients) {
						
						if(clientIp.trim().equals(c.IP) && c.udpPort == 0) {
							c.setUdpPort(packet.getPort());
						}
					}