您的位置:首页 > 编程语言 > Java开发

Java Socket 编程学习(3)

2014-01-15 14:52 113 查看
Java Socket 编程学习,利用DatagramSocket和DatagramPacket实现UDP数据传输

场景描述:

客户端创建数据包,绑定服务器地址和端口,向服务器发送数据;服务器绑定端口,从端口接受数据

服务器代码:

ServerBean类

package yang.socket.udp;

import java.io.IOException;

import java.net.DatagramPacket;

import java.net.InetAddress;

import java.net.InetSocketAddress;

import java.net.DatagramSocket;

import java.net.SocketException;

import java.net.UnknownHostException;

public class ServerBean {

	// 描述UDP通讯的DatagramSocket对象

	private DatagramSocket ds;

	// 用来封装通讯字符串

	private byte buffer[];

	// 服务器端的端口号

	private int serverport;

	// 通讯内容

	private String content;

	// 描述通讯地址,此类表示互联网协议 (IP) 地址。

	private InetAddress addr;

	// 此类实现 IP 套接字地址(IP 地址 + 端口号)

	private InetSocketAddress sd;

	// 此类表示数据报包

	private DatagramPacket dp;

	// 以下是各属性的Get和Set类型方法

	public DatagramSocket getDs() {
		
		return ds;
	}

	public void setDs(DatagramSocket ds) {
		
		this.ds = ds;
	}

	public byte[] getBuffer() {
		
		return buffer;
	}

	public void setBuffer(byte[] buffer) {
		
		this.buffer = buffer;
	}

	public int getServerport() {
		
		return serverport;
	}

	public void setServerport(int serverport) {
		
		this.serverport = serverport;
	}

	public String getContent() {
		
		return content;
	}

	public void setContent(String content) {
		
		this.content = content;
	}

	public InetAddress getAddr() {
		
		return addr;
	}

	public void setAddr(InetAddress addr) {
		
		this.addr = addr;
	}

	public InetSocketAddress getSd() {
		
		return sd;
	}

	public void setSd(InetSocketAddress sd) {
		
		this.sd = sd;
	}

	public DatagramPacket getDp() {
		
		return dp;
	}

	public void setDp(DatagramPacket dp) {
		
		this.dp = dp;
	}

	public ServerBean(int port, InetAddress addr) throws SocketException,
			UnknownHostException

	{

		this.buffer = new byte[1024];

		this.serverport = port;

		this.content = "";

		this.ds = null;

		this.setAddr(addr);

		this.dp = null;

		this.sd = null;

	}

	public void bind(InetAddress addr, int port) throws SocketException,
			UnknownHostException {

		// 创建数据报套接字并将其绑定到本地主机上的指定端口

		ds = new DatagramSocket(null);

		// 创建地址,本地地址

		sd = new InetSocketAddress(addr, port);

		// 绑定本地地址,在此端口接受消息

		ds.bind(sd);
		
		// System.out.println("服务器绑定端口 " + port);
		
		// System.out.println(ds.getLocalSocketAddress());
	}

	public void listenClient() throws IOException

	{

		// 在循环体里接收消息

		while (true)

		{

			// 初始化DatagramPacket类型的变量DatagramPacket,用来接收长度为 length 的数据包

			dp = new DatagramPacket(buffer, buffer.length);

			// 接收消息,并把消息通过dp参数返回

			ds.receive(dp);

			content = new String(dp.getData(), 0, dp.getLength());

			System.out.println(content);

			System.out.println("Message From " + dp.getSocketAddress());
			

		}

	}

}


UDPServer类

package yang.socket.udp;

import java.io.IOException;
import java.net.InetAddress;

public class UDPServer {
	
	public static int serverport;
	
	public static InetAddress localaddr;

	public static void main(String args[]) throws IOException

	{
		serverport = 1986;
		
		localaddr = InetAddress.getLocalHost();
		
		System.out.println("服务器端启动,绑定端口 " + serverport);

		ServerBean server = new ServerBean(serverport, localaddr);
		
		server.bind(localaddr, serverport);

		System.out.println("Message Recevied:");

		server.listenClient();

	}

}


客户端代码:

ClientBean类

package yang.socket.udp;

import java.io.IOException;

import java.net.DatagramPacket;

import java.net.InetSocketAddress;

import java.net.DatagramSocket;

import java.net.InetAddress;

import java.net.SocketException;

import java.net.UnknownHostException;

public class ClientBean {

	// 描述UDP通讯的DatagramSocket对象,表示用来发送和接收数据报包的套接字

	private DatagramSocket ds;

	// 此类表示数据报包
	
	private DatagramPacket dp;
	
	//此类实现 IP 套接字地址(IP 地址 + 端口号)
	
	private InetSocketAddress sd;

	// 用来封装通讯字符串

	private byte buffer[];

	// 客户端的端口号

	private int clientport;

	// 服务器端的端口号

	private int serverport;

	// 通讯内容

	private String content;

	// 描述通讯地址,此类表示互联网协议 (IP) 地址。

	private InetAddress localaddr;
	
	private InetAddress serveraddr;

	// 以下是各属性的Get和Set类型方法

	public DatagramSocket getDs() {
		
		return ds;
	}

	public void setDs(DatagramSocket ds) {
		
		this.ds = ds;
	}

	public DatagramPacket getDp() {
		
		return dp;
	}

	public void setDp(DatagramPacket dp) {
		
		this.dp = dp;
	}

	public InetSocketAddress getSd() {
		
		return sd;
	}

	public void setSd(InetSocketAddress sd) {
		
		this.sd = sd;
	}

	public byte[] getBuffer() {
		
		return buffer;
	}

	public void setBuffer(byte[] buffer) {
		
		this.buffer = buffer;
	}

	public int getClientport() {
		
		return clientport;
	}

	public void setClientport(int clientport) {
		
		this.clientport = clientport;
	}

	public int getServerport() {
		
		return serverport;
	}

	public void setServerport(int serverport) {
		
		this.serverport = serverport;
	}

	public String getContent() {
		
		return content;
	}

	public void setContent(String content) {
		
		this.content = content;
	}

	public InetAddress getLocaladdr() {
		
		return localaddr;
	}

	public void setLocaladdr(InetAddress localaddr) {
		
		this.localaddr = localaddr;
	}

	public InetAddress getServeraddr() {
		
		return serveraddr;
	}

	public void setServeraddr(InetAddress serveraddr) {
		
		this.serveraddr = serveraddr;
	}

	public ClientBean(int clientport, int serverport, InetAddress serveraddr, InetAddress localaddr) throws SocketException,
			UnknownHostException
	{

		this.buffer = new byte[1024];

		this.clientport = clientport;

		this.serverport = serverport;
		
		this.content = "";
		
		this.ds = null; 
		
		this.serveraddr = serveraddr;
		
		this.localaddr = localaddr;
		
		this.dp = null;
		
		this.sd = null;

	}

	public void bind(InetAddress addr, int clientport) throws SocketException, UnknownHostException{
		
		// 创建数据报套接字并将其绑定到本地主机上的指定端口
		ds =  new DatagramSocket(null); 
		//创建地址,本地地址
		sd = new InetSocketAddress(addr, clientport);
		//将此 DatagramSocket 绑定到特定的地址和端口
		ds.bind(sd);
	}
	
	public void sendToServer() throws IOException

	{

		buffer = content.getBytes();

		// 构造数据报包,用来将长度为 length的包发送到指定主机上的指定端口号。
		dp = new DatagramPacket(buffer, content.length(), serveraddr, serverport);
		
		// 发送数据包
		ds.send(dp);

	}

}


UDPClient类

package yang.socket.udp;

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStreamReader;

import java.net.InetAddress;

public class UDPClient implements Runnable

{
	public static String content;
	
	public static int clientport;
	
	public static int serverport;
	
	public static InetAddress serveraddr;
	
	public static InetAddress localaddr;

	public static ClientBean client;

	public void run()

	{
		try

		{
			// 设置发送消息体内容
			client.setContent(content);
			// 发送消息
			client.sendToServer();

		}

		catch (Exception ex)

		{

			System.err.println(ex.getMessage());

		}
		
	}

	public static void main(String args[]) throws IOException

	{

		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		
		clientport = 1985;

		serverport = 1986;
		
		//发送的serverIP地址
		byte[] bs = new byte[] { (byte) 192, (byte) 168, (byte) 30, (byte) 13 };
		
		serveraddr = InetAddress.getByAddress(bs);
		
		localaddr = InetAddress.getLocalHost();
		
		client = new ClientBean(clientport, serverport, serveraddr, localaddr);
		//讲套接字绑定到本地
		client.bind(localaddr, clientport);

		System.out.println("客户端启动");
		
		System.out.print("Server Address: ");
		//获取套接字连接的地址
		System.out.print("HostName " + client.getServeraddr().getHostName());
		
		System.out.print(" Address " + client.getServeraddr().getHostAddress());
		
		System.out.print(" Port " + client.getServerport() + "\n");

		System.out.print("Local Address:  ");
		//获取套接字绑定的本地地址
		System.out.print("HostName " + client.getDs().getLocalAddress().getHostName());
		
		System.out.print(" Address " + client.getDs().getLocalAddress().getHostAddress());
		
		System.out.print(" port " + client.getDs().getLocalPort() + "\n");
		
		System.out.println("请输入发送内容,回车发送,键入end时发送结束");

		while (true)

		{

			// 接收用户输入
			content = br.readLine();

			// 如果是end或空,退出循环

			if (content == null || content.equalsIgnoreCase("end")
					|| content.equalsIgnoreCase(""))

			{
				break;
			}
			
			// 开启新线程,发送消息
			// 每次输入一次消息,就新建一个线程和连接
			new Thread(new UDPClient()).start();
			

		}
		
		System.out.println("连接套接字断开关闭");
		
		client.getDs().disconnect();
		
		client.getDs().close();
		
	}

}


测试运行:

UDPClient

客户端启动
Server Address: HostName Lenovo-PC Address 192.168.30.13 Port 1986
Local Address:  HostName Lenovo-PC Address 192.168.30.13 port 1985
请输入发送内容,回车发送,键入end时发送结束
nihao
this is a udp test
end
连接套接字断开关闭


UDPServer

服务器端启动,绑定端口 1986
Message Recevied:
nihao
Message From /192.168.30.13:1985
this is a udp test
Message From /192.168.30.13:1985
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: