Java Socket 程式設計學習(4)
阿新 • • 發佈:2019-01-08
Java 利用Socket實現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() throws SocketException, UnknownHostException { // 建立資料報套接字並將其繫結到本地主機上的指定埠 ds = new DatagramSocket(null); // 建立地址,本地地址 sd = new InetSocketAddress(addr, serverport); // 繫結本地地址,在此埠接受訊息 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()); if(content.equalsIgnoreCase("end")){ System.out.println("The Message is over, client socket has closed."); } } } }
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(); 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() throws SocketException, UnknownHostException{ // 建立資料報套接字並將其繫結到本地主機上的指定埠 ds = new DatagramSocket(null); //建立地址,本地地址 sd = new InetSocketAddress(localaddr, 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;
import java.net.SocketException;
import java.net.UnknownHostException;
class ClientBeanThread implements Runnable{
private ClientBean client;
public ClientBeanThread(int clientport, int serverport, InetAddress serveraddr, InetAddress localaddr) throws SocketException, UnknownHostException{
this.client = new ClientBean(clientport, serverport, serveraddr, localaddr);;
}
public ClientBean getClient() {
return client;
}
public void setClient(ClientBean client) {
this.client = client;
}
public void SendMessage() throws IOException{
client.sendToServer();
}
public void bind() throws SocketException, UnknownHostException{
client.bind();
}
public void setContent(String content){
client.setContent(content);
}
public void run() {
try {
SendMessage();
}catch (IOException e) {
e.printStackTrace();
}
}
}
public class UDPClient{
public static int clientport;
public static int serverport;
public static String content;
static byte[] ip;
static InetAddress serveraddr;
static InetAddress localaddr;
static BufferedReader input;
static ClientBeanThread client;
public static void main(String args[]) throws IOException, InterruptedException
{
clientport = 1985;
serverport = 1986;
ip = new byte[] { (byte) 192, (byte) 168, (byte) 30, (byte) 13 };
serveraddr = InetAddress.getByAddress(ip);
localaddr = InetAddress.getLocalHost();
input = new BufferedReader(new InputStreamReader(System.in));
client = new ClientBeanThread(clientport, serverport, serveraddr, localaddr);
client.bind();
System.out.println("客戶端啟動");
System.out.print("Server Address: ");
//獲取套接字連線的地址
System.out.print("HostName " + client.getClient().getServeraddr().getHostName());
System.out.print(" Address " + client.getClient().getServeraddr().getHostAddress());
System.out.print(" Port " + client.getClient().getServerport() + "\n");
System.out.print("Local Address: ");
//獲取套接字繫結的本地地址
System.out.print("HostName " + client.getClient().getDs().getLocalAddress().getHostName());
System.out.print(" Address " + client.getClient().getDs().getLocalAddress().getHostAddress());
System.out.print(" port " + client.getClient().getDs().getLocalPort() + "\n");
System.out.println("請輸入傳送內容,回車傳送,鍵入end時傳送結束");
while(true){
content = input.readLine();
client.setContent(content);
new Thread(client).start();
if (content.equalsIgnoreCase("end")){
System.out.println("Send is over.");
break;
}
}
Thread.sleep(2000);
System.out.println("Socket has closed.");
client.getClient().getDs().disconnect();
client.getClient().getDs().close();
}
}
測試執行:
客戶端
客戶端啟動
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
Send is over.
Socket has closed.
伺服器端
伺服器端啟動,繫結埠 1986
Message Recevied:
nihao
Message From /192.168.30.13:1985
this is a udp test
Message From /192.168.30.13:1985
end
Message From /192.168.30.13:1985
The Message is over, client socket has closed.