现在的位置: 首页 > 综合 > 正文

java socket编程(基础)

2013年09月27日 ⁄ 综合 ⁄ 共 16355字 ⁄ 字号 评论关闭

一、网络编程中两个主要的问题

一个是如何准确的定位网络上一台或多台主机,另一个就是找到主机后如何可靠高效的进行数据传输。

在TCP/IP协议中IP层主要负责网络主机的定位,数据传输的路由,由IP地址可以唯一地确定Internet上的一台主机。

而TCP层则提供面向应用的可靠(tcp)的或非可靠(UDP)的数据传输机制,这是网络编程的主要对象,一般不需要关心IP层是如何处理数据的。

目前较为流行的网络编程模型是客户机/服务器(C/S)结构。即通信双方一方作为服务器等待客户提出请求并予以响应。客户则在需要服务时向服务器提 出申请。服务器一般作为守护进程始终运行,监听网络端口,一旦有客户请求,就会启动一个服务进程来响应该客户,同时自己继续监听服务端口,使后来的客户也 能及时得到服务。

二、两类传输协议:TCP、UDP

TCPTranfer Control Protocol的简称,即流式Socket(SOCK_STREAM)是一种面向连接的保证可靠传输的协议。通过TCP协议传输,得到的是一个顺序的无差错的数据流。发送方和接收方的成对的两个socket之间必须建
立连接,以便在TCP协议的基础上进行通信,当一个socket(通常都是server socket)等待建立连接时,另一个socket可以要求进行连接,一旦这两个socket连接起来,它们就可以进行双向数据传输,双方都可以进行发送 或接收操作。

UDPUser Datagram Protocol的简称,即数据报式Socket(SOCK_DGRAM),是一种无连接的协议,每个数据报都是一个独立的信息,包括完整的源地址或目的地址,它在网络上以任何可能的路径传往目的地,因此能否到达目的地,到达目的地的时间以及内容的正确性都是不能被保证的。

比较:

UDP:

1、每个数据报中都给出了完整的地址信息,因此无需要建立发送方和接收方的连接。

2、UDP传输数据时是大小限制的,每个被传输的数据报必须限定在64KB之内

3、UDP是一个不可靠的协议,发送方所发送的数据报并不一定以相同的次序到达接收方

TCP:

1、面向连接的协议,在socket之间进行数据传输之前必然要建立连接,所以在TCP中需要连接

时间。

2、TCP传输数据大小限制,一旦连接建立起来,双方的socket就可以按统一的格式传输大的

数据。

3、TCP是一个可靠的协议,它确保接收方完全正确地获取发送方所发送的全部数据。

应用:

1、TCP在网络通信上有极强的生命力,例如远程连接(Telnet)和文件传输(FTP)都需要不定长度的数据被可靠地传输。但是可靠的传输是要付出代价的,对数据内容正确性的检验必然占用计算机的处理时间和网络的带宽,因此TCP传输的效率不如UDP

2、UDP操作简单,而且仅需要较少的监护,因此通常用于局域网高可靠性的分散系统中client/server应用程序。例如视频会议系统,并不要求音频视频数据绝对的正确,只要保证连贯性就可以了,这种情况下显然使用UDP会更合理一些。

 

三、基于Socket的java网络编程

1、什么是Socket

网络上的两个程序通过一个双向的通讯连接实现数据的交换,这个双向链路的一端称为一个Socket。Socket通常用来实现客户方和服务方的连接。Socket是TCP/IP协议的一个十分流行的编程界面,一个Socket由一个IP地址和一个端口号唯一确定。

但是,Socket所支持的协议种类也不光TCP/IP一种,因此两者之间是没有必然联系的。在Java环境下,Socket编程主要是指基于TCP/IP协议的网络编程。

2、Socket通讯的过程

Server端Listen(监听)某个端口是否有连接请求,Client端向Server 端发出Connect(连接)请求,Server端向Client端发回Accept(接受)消息。一个连接就建立起来了。Server端和Client 端都可以通过Send,Write等方法与对方通信。

对于一个功能齐全的Socket,都要包含以下基本结构,其工作过程包含以下四个基本的步骤:

  (1) 创建Socket;

  (2) 打开连接到Socket的输入/出流;

  (3) 按照一定的协议对Socket进行读/写操作;

  (4) 关闭Socket.(在实际应用中,并未使用到显示的close,虽然很多文章都推荐如此,不过在我的程序中,可能因为程序本身比较简单,要求不高,所以并未造成什么影响。)

3、创建Socket

java(jdk 1.6.0)在包java.net中提供了两个类Socket和ServerSocket,分别用来表示双向连接的客户端和服务端。这是两个封装得非常好的类,使用很方便。其构造方法如下:

TCP/IP:

Socket()
通过系统默认类型的 SocketImpl 创建未连接套接字。

Socket(InetAddress address, int port)创建一个流套接字并将其连接到指定 IP 地址的指定端口号。 

Socket(InetAddress host, int port, boolean stream)已过时( Use DatagramSocket instead for UDP transport)。

Socket(InetAddress address, int port,InetAddress localAddr, int localPort)创建一个套接字并将其连接到指定远程地址上的指定远程端口。 

Socket(Proxy proxy)创建一个未连接的套接字并指定代理类型(如果有),该代理不管其他设置如何都应被使用。

protected Socket(SocketImpl impl)使用用户指定的 SocketImpl 创建一个未连接 Socket。

Socket(String host, int port)创建一个流套接字并将其连接到指定主机上的指定端口号。

Socket(String host, int port, boolean stream)已过时( 使用 DatagramSocket 取代 UDP 传输。) 

Socket(String host, int port,InetAddress localAddr, int localPort)创建一个套接字并将其连接到指定远程主机上的指定远程端口。

ServerSocket()创建非绑定服务器套接字。

ServerSocket(int port)创建绑定到特定端口的服务器套接字。

ServerSocket(int port, int backlog)利用指定的 backlog 创建服务器套接字并将其绑定到指定的本地端口号。

ServerSocket(int port, int backlog,InetAddress bindAddr)使用指定的端口、侦听 backlog 和要绑定到的本地 IP 地址创建服务器。

UDP:

DatagramSocket()构造数据报套接字并将其绑定到本地主机上任何可用的端口。

protected DatagramSocket(DatagramSocketImpl impl)创建带有指定 DatagramSocketImpl 的未绑定数据报套接字。

DatagramSocket(int port)创建数据报套接字并将其绑定到本地主机上的指定端口。

DatagramSocket(int port,InetAddress laddr)创建数据报套接字,将其绑定到指定的本地地址。 

DatagramSocket(SocketAddress bindaddr)创建数据报套接字,将其绑定到指定的本地套接字地址。

DatagramPacket(byte[] buf, int length) 构造DatagramPacket,用来接收长度为length 的数据包。

DatagramPacket(byte[] buf, int length,InetAddress address, int port) 构造数据报包,用来将长度为length 的包发送到指定主机上的指定端口号。

DatagramPacket(byte[] buf, int offset, int length) 构造DatagramPacket,用来接收长度为length 的包,在缓冲区中指定了偏移量。

DatagramPacket(byte[] buf, int offset, int length,InetAddress address, int port) 构造数据报包,用来将长度为length 偏移量为offset 的包发送到指定主机上的指定端口号。

DatagramPacket(byte[] buf, int offset, int length,SocketAddress address) 构造数据报包,用来将长度为length 偏移量为offset 的包发送到指定主机上的指定端口号。

DatagramPacket(byte[] buf, int length,SocketAddress address) 构造数据报包,用来将长度为length 的包发送到指定主机上的指定端口号。


DatagramSocket的几个重要方法:
(1) DatagramSocket(): 随机绑定一个有效的端口;
(2) DatagramSocket(int port):绑定指定的端口;
(3) Void send(DatagramPacket p):发送数据报,由于目的地的地址信息已包含在数据报中,所以不需要在本函数中提 供地址信息;
(4) synchronized void receive(DatagramPacket p):接收数据包,线程安全;
(5) synchronized void close():关闭socket
在DatagramSocket中并不区分 ServerSocket和ClientSocket,如果一定要区分,那么发送的是client, 而接收的是server

DatagramPacket有 以几个重要的方法:
(1) DatagramPacket(byte ibuf[], int ilength):用于接收数据报;
(2) DatagramPacket(byte ibuf[], int ilength, InetAddress iaddr, int iport):用于发送的数据 报;
(3) byte[] getData()
(4) int getLength() 。

其中address、host和port分别是双向连接中另一方的IP地址、主机名和端 口号,stream指明socket是流socket还是数据报socket,localPort表示本地主机的端口号,localAddr和 bindAddr是本地机器的地址(ServerSocket的主机地址),impl是socket的父类,既可以用来创建serverSocket又可以用来创建Socket。count则表示服务端所能支持的最大连接数。

  Socket client = new Socket("127.0.01.", 80);

  ServerSocket server = new ServerSocket(80);

  注意,在选择端口时,必须小心。每一个端口提供一种特定的服务,只有给出正确的端口,才 能获得相应的服务。0~1023的端口号为系统所保留,例如http服务的端口号为80,telnet服务的端口号为21,ftp服务的端口号为23, 所以我们在选择端口号时,最好选择一个大于1023的数以防止发生冲突。

  在创建socket时如果发生错误,将产生IOException,在程序中必须对之作出处理。所以在创建Socket或ServerSocket是必须捕获或抛出例外。

 4、实例演示

(1)TCP/IP协议的简单例子

  • 一个server对一个client
server端:
package socket_one2one;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class MyServer {
	
	public static void doServerSocket(){
		try{
			ServerSocket server=null;
			
			try{
				//创建端口4800的监听对象,监听客户请求
				server=new ServerSocket(4800);
			}catch(Exception e) {
				System.out.println("can not listen to:"+e);
			}
			
			Socket socket=null;
			try{
				//使用accept()阻塞等待客户请求,有客户请求到来则产生一个Socket对象,并继续执行
				socket=server.accept();

			}catch(Exception e) {
				System.out.println("Error."+e);
			}

			String line;
			
			//由Socket对象得到输入流,并构造相应的BufferedReader对象
			BufferedReader socket_is=new BufferedReader(new InputStreamReader(socket.getInputStream()));

			//由Socket对象得到输出流,并构造PrintWriter对象
			PrintWriter socket_os=new PrintWriter(socket.getOutputStream());
			
			//由系统标准输入设备构造BufferedReader对象,获取标准输入行
			BufferedReader sysin=new BufferedReader(new InputStreamReader(System.in));
			
			//在标准输出上打印从客户端socket读入的字符串
			System.out.println("**Client:"+socket_is.readLine());
			
			//从标准输入读入一字符串
			System.out.print("Server:");
			line=sysin.readLine();
			System.out.println("");
			
			//如果该字符串为 "bye",则停止循环
			while(!line.equals("bye")){
				//向Client输出该字符串
				socket_os.println(line);
				
				//刷新输出流,使Client马上收到该字符串
				socket_os.flush();
				
				//从Client读入一字符串,并打印到标准输出上
				System.out.println("**Client:"+socket_is.readLine());
				
				//从系统标准输入读入一字符串
				System.out.print("**Server:");
				line=sysin.readLine();
				System.out.println("");
			}//继续循环
			socket_os.close(); //关闭Socket输出流
			socket_is.close(); //关闭Socket输入流
			socket.close(); //关闭Socket
			server.close(); //关闭ServerSocket
		}catch(IOException e){
			System.out.println("Error:"+e);
		}

		
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		MyServer.doServerSocket();

	}

}

client端:
package socket_one2one;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

public class MyClient {

	public static void doSocket(){
		
		try {
			
			//向本地4800端口发出客户请求
			Socket socket=new Socket("127.0.0.1",4800);
			
			//由系统标准输入构造bufferedReader对象
			BufferedReader sysin=new BufferedReader(new InputStreamReader(System.in));
			
			//Socket对象得到输出流,并构造PrintWriter对象
			PrintWriter socket_os=new PrintWriter(socket.getOutputStream());
		
			//由socket对象得到输入流,并构造相应的BufferdReader对象
			BufferedReader socket_is=new BufferedReader(new InputStreamReader(socket.getInputStream()));

			String readline;
			//从系统标准输入读入一行字符串
			System.out.print("**Client:");
			readline=sysin.readLine(); 
			System.out.println("");
			
			//若从标准输入读入的字符串为 "bye"则停止循环
			while(!readline.equals("bye")){
				
				//将从系统标准输入读入的字符串输出到Server
				socket_os.println(readline);
				//刷新输出流,使Server马上收到该字符串
				socket_os.flush();
				
				//从Server读入一字符串,并打印到标准输出上
				System.out.println("**Server:"+socket_is.readLine());
				
				//从系统标准输入读入一字符串
				System.out.print("**Client:");
				readline=sysin.readLine(); 
				System.out.println("");
			} //继续循环
			socket_os.close(); //关闭Socket输出流
			socket_is.close(); //关闭Socket输入流
			socket.close(); //关闭Socket
			
		} catch (IOException e) {
			e.printStackTrace();
		}
		

	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		MyClient.doSocket();

	}

}

  • 一个server对多个client
client端:
package socket_one2several;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;


/**
 * 客户端Socket
 * one Server 2 several Client
 * 
 */
public class MyClient {


	public static void doSocket(){
		
		try {
			
			//向本地4899端口发出客户请求
			Socket socket=new Socket("127.0.0.1",4899);
			
			//由系统标准输入构造bufferedReader对象
			BufferedReader sysin=new BufferedReader(new InputStreamReader(System.in));
			
			//Socket对象得到输出流,并构造PrintWriter对象
			PrintWriter socket_os=new PrintWriter(socket.getOutputStream());
		
			//由socket对象得到输入流,并构造相应的BufferdReader对象
			BufferedReader socket_is=new BufferedReader(new InputStreamReader(socket.getInputStream()));

			String readline;
			//从系统标准输入读入一行字符串
			System.out.print("[Client]:");
			readline=sysin.readLine(); 
			System.out.println("");
			
			//若从标准输入读入的字符串为 "bye"则停止循环
			while(!readline.equals("bye")){
				
				//将从系统标准输入读入的字符串输出到Server
				socket_os.println(readline);
				//刷新输出流,使Server马上收到该字符串
				socket_os.flush();
				
				//从Server读入一字符串,并打印到标准输出上
				System.out.println("[Server]:"+socket_is.readLine());
				
				//从系统标准输入读入一字符串
				System.out.print("[Client]:");
				readline=sysin.readLine(); 
				System.out.println("");
			} //继续循环
			socket_os.close(); //关闭Socket输出流
			socket_is.close(); //关闭Socket输入流
			socket.close(); //关闭Socket
			
		} catch (IOException e) {
			e.printStackTrace();
		}
		

	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		MyClient.doSocket();

	}

}

server端:

package socket_one2several;


import java.net.ServerSocket;

/**
 * 服务器端Socket
 * one Server 2 several Client
 */

public class MyServer {

	 //服务器端Socket对象
	private static ServerSocket server = null; 
	
	public static void doServerSocket() {
		try {

			// 统计客户端总数
			int clientCount = 0; 
			//是否对客户端进行监听
			boolean listening = true; 

			try {
				//创建端口4899的监听对象,监听客户请求
				server = new ServerSocket(4899);
				
			} catch (Exception e) {
				System.out.println("Can not listen to. " + e);
			}

			while (listening) {
				//客户端计数
				clientCount++;

				//监听到客户请求,根据得到的Socket对象和客户计数创建服务线程,并启动
				new MyServerThread(server.accept(), clientCount).start();
				
			}
		} catch (Exception e) {
			System.out.println("Error. " + e);
		}
	}

	/**
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		MyServer.doServerSocket();
	}
}

server端调用的多线程,处理多个client的socket:

package socket_one2several;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

public class MyServerThread extends Thread {

	//保存本进程的客户计数
	private static int cNumber= 0; 

	//保存与本线程相关的Socket对象
	private Socket socket = null; 

	public MyServerThread(Socket socket, int clientCount) {

		this.socket = socket;
		cNumber = clientCount;
		System.out.println("当前在线的用户数: " + cNumber);
	}

	public void run() {
		try {

			// 由Socket对象得到输入流,并构造相应的BufferedReader对象
			BufferedReader socket_in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

			// 由Socket对象得到输出流,并构造PrintWriter对象
			PrintWriter socket_out = new PrintWriter(socket.getOutputStream());

			// 由系统标准输入设备构造BufferedReader对象
			BufferedReader sysin = new BufferedReader(new InputStreamReader(System.in));

			// 在标准输出上打印从客户端读入的字符串
			System.out.println("[Client " + cNumber + "]: " + socket_in.readLine());

			String line; // 保存一行内容

			// 从标准输入读入一字符串
			line = sysin.readLine();

			while (!line.equals("bye")) { // 如果该字符串为 "bye",则停止循环

				// 向Client输出该字符串
				socket_out.println(line);

				// 刷新输出流,使Client马上收到该字符串
				socket_out.flush();

				System.out.print("[Server]: "+line);
				
				// 从Client读入一字符串,并打印到标准输出上
				System.out.println("[Client " + cNumber + "]: " + socket_in.readLine());

				// 从系统标准输入读入一字符串
				line = sysin.readLine();

			}

			socket_out.close(); // 关闭Socket输出流
			socket_in.close(); // 关闭Socket输入流
			socket.close(); // 关闭Socket
			
		} catch (Exception e) {
			System.out.println("Error. " + e);
		}
	}

}
(2)UDP协议的简单例子

 server端:

package socket_udp_one2one;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketException;

public class UDPServerSocket {
	//报文数组
	private byte[] buffer = new byte[1024];

	//接收发送DatagramSocket
	private DatagramSocket datagramSocket = null;
	//数据报处理对象
	private DatagramPacket packet = null;
	//用于描述和包装一个Internet IP地址的对象
	private InetSocketAddress socketAddress = null;
	//IP地址
	private String hostIP;

	public String getHostIP() {
		return hostIP;
	}


	/**
	 * 构造函数,绑定主机和端口.
	 * 
	 * @param host 主机
	 * @param port 端口
	 * @throws Exception
	 */
	public UDPServerSocket(String host, int port) throws Exception {
		this.bind(host, port);
	}

	/**
	 * 绑定监听地址和端口.
	 * 
	 * @param host  主机IP
	 * @param port  端口
	 * @throws SocketException
	 */
	public final void bind(String host, int port) throws SocketException {
		socketAddress = new InetSocketAddress(host, port);
		datagramSocket = new DatagramSocket(socketAddress);
	}

	/**
	 * 接收数据包,该方法会造成线程阻塞.
	 * 
	 * @return 返回接收的数据串信息
	 * @throws IOException
	 */
	public final String receive() throws IOException {
		packet = new DatagramPacket(buffer, buffer.length);
		datagramSocket.receive(packet);
		hostIP = packet.getAddress().getHostAddress();

		String info = new String(packet.getData(), 0, packet.getLength());
		System.out.println("[来自 "+packet.getPort()+" 客户端]:" + info);
		return info;
	}

	/**
	 * 将响应包发送给请求端.
	 * 
	 * @param bytes 回应报文
	 * @throws IOException
	 */
	public final void response(String info) throws IOException {
		DatagramPacket dp = new DatagramPacket(buffer, buffer.length,
				packet.getAddress(), packet.getPort());
		dp.setData(info.getBytes());
		datagramSocket.send(dp);
	}

	
	/**
	 * 设置超时时间,该方法必须在bind方法之后使用.
	 * 
	 * @param timeout 超时时间
	 * @throws Exception
	 */
	public final void setSoTimeout(int timeout) throws Exception {
		datagramSocket.setSoTimeout(timeout);
	}

	/**
	 * 获得超时时间.
	 * 
	 * @return 返回超时时间.
	 * @throws Exception
	 */
	public final int getSoTimeout() throws Exception {
		return datagramSocket.getSoTimeout();
	}

	
	/**
	 * 设置报文的缓冲长度.
	 * 
	 * @param bufsize 缓冲长度
	 */
	public final void setLength(int bufsize) {
		packet.setLength(bufsize);
	}

	/**
	 * 获得发送回应的IP地址.
	 * 
	 * @return 返回回应的IP地址
	 */
	public final InetAddress getResponseAddress() {
		return packet.getAddress();
	}

	/**
	 * 获得回应的主机的端口
	 * 
	 * @return 返回回应的主机的端口
	 */
	public final int getResponsePort() {
		return packet.getPort();
	}

	/**
	 * 关闭udp监听口.
	 * 
	 */
	public final void close() {
		try {
			datagramSocket.close();
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

	/**
	 * 用线程处理多个client
	 * @throws Exception 
	 */
	public static void doDatagramSocket() throws Exception{
		String serverHost = "127.0.0.1";
		int serverPort = 5566;
		boolean listening=true;
		String context=null;
		// 由系统标准输入设备构造BufferedReader对象
		BufferedReader sysin = new BufferedReader(new InputStreamReader(System.in));
		
		UDPServerSocket udpServerSocket = new UDPServerSocket(serverHost,serverPort);
		while (listening) {
			udpServerSocket.receive();
			context=sysin.readLine().toString();
			udpServerSocket.response(context);

		}
	}
	
	/**
	 * 测试方法.
	 * 
	 * @param args
	 * @throws Exception
	 */
	public static void main(String[] args) throws Exception {
		UDPServerSocket.doDatagramSocket();
	}

}

client端:

 

package socket_udp_one2one;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

/**
 * UDP客户端程序,用于对服务端发送数据,并接收服务端的回应信息.
 */
public class UDPClientSocket {
	//数据报数组
	private byte[] buffer = new byte[1024];

	private DatagramSocket datagramSocket = null;
	//获取datagramSocket
	public DatagramSocket getDatagramSocket() {
		return datagramSocket;
	}


	/**
	 * 构造函数,创建UDP客户端
	 * 
	 * @throws Exception
	 */
	public UDPClientSocket() throws Exception {
		datagramSocket = new DatagramSocket();
	}

	/**
	 * 向指定的服务端发送数据信息.
	 * 
	 * @param host	服务器主机地址
	 * @param port	服务端端口
	 * @param bytes	发送的数据信息
	 * @return 	返回构造后俄数据报
	 * @throws IOException
	 */
	public final DatagramPacket send(final String host, final int port,
			final byte[] bytes) throws IOException {
		DatagramPacket dp = new DatagramPacket(bytes, bytes.length,
				InetAddress.getByName(host), port);
		datagramSocket.send(dp);
		return dp;
	}

	/**
	 * 接收从指定的服务端发回的数据.
	 * 
	 * @param lhost服务端主机
	 * @param lport服务端端口
	 * @return 返回从指定的服务端发回的数据.
	 * @throws Exception
	 */
	public final String receive(final String lhost, final int lport)
			throws Exception {
		DatagramPacket dp = new DatagramPacket(buffer, buffer.length);
		datagramSocket.receive(dp);
		String info = new String(dp.getData(), 0, dp.getLength());
		return info;
	}
	
	/**
	 * 设置超时时间,该方法必须在bind方法之后使用.
	 * 
	 * @param timeout超时时间
	 * @throws Exception
	 */
	public final void setSoTimeout(final int timeout) throws Exception {
		datagramSocket.setSoTimeout(timeout);
	}

	/**
	 * 获得超时时间.
	 * 
	 * @return 返回超时时间
	 * @throws Exception
	 */
	public final int getSoTimeout() throws Exception {
		return datagramSocket.getSoTimeout();
	}

	/**
	 * 关闭UDP连接.
	 * 
	 */
	public final void close() {
		try {
			datagramSocket.close();
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

	/**
	 * 客户端处理
	 * @throws Exception
	 */
	public static void doUDPClientSocket() throws Exception{
		UDPClientSocket client = new UDPClientSocket();
		String serverHost = "127.0.0.1";
		int serverPort = 5566;
		boolean conectFlag=true;
		
		String context="";
		System.out.print("[请输入]:");
		// 由系统标准输入设备构造BufferedReader对象
		BufferedReader sysin = new BufferedReader(new InputStreamReader(System.in));
		context=sysin.readLine().toString();
		while(conectFlag){
			client.send(serverHost, serverPort, context.getBytes());
			System.out.println("[向服务端发送]:" + context);
			String info = client.receive(serverHost, serverPort);
			if(!info.equals("")||info!=null)
				System.out.println("[来自服务端响应]:" + info);
			context=sysin.readLine().toString();
		}
		
	}
	
	/**
	 * 测试客户端发包和接收回应信息的方法.
	 * 
	 * @param args
	 * @throws Exception
	 */
	public static void main(String[] args) throws Exception {
		UDPClientSocket.doUDPClientSocket();
	}
}

 

 

参考:

java socket编程 http://www.cnblogs.com/linzheng/archive/2011/01/23/1942328.html

Java中的UDP协议编程 http://www.blogjava.net/amigoxie/archive/2007/08/16/137413.html

拓展NIO实现socket:

http://blog.csdn.net/kongxx/article/details/7288896

http://www.iteye.com/topic/195020

http://yangguangfu.iteye.com/blog/774194

抱歉!评论已关闭.