UDP编程
UPD: User Datagram Protocol。面向无连接,不安全。
UDP中,发送方无需知道接收方是否接受,只考虑将数据通过IP+port发送过去。
此方法简单,经济。
类:DatagramSocket: 数据通讯管道。
方法:send,receive。
类:DatagramPacket:集装箱,用于封装数据,加上目的地(IP+port)
发送方代码:
- 建立数据通讯通道,
- 编写要发送的数据,
- 创建集装箱对象,并给其目的地地址。
- 将数据送入通道。
后面为发送方作为接收方,接受对方的数据。通道已经建立,只需要创建集装箱对象接收通道中的数据即可。
//发送方
package UDPtest;
import java.io.IOException;
import java.net.*;
public class UDPsend {
public static void main(String[] args) throws IOException {
DatagramSocket ds = new DatagramSocket();
String str = "Hello world!";
DatagramPacket dp = new DatagramPacket(str.getBytes(), str.length(), InetAddress.getByName("127.0.0.1"), 3000);
System.out.println("正在发送数据!");
ds.send(dp);
System.out.println("数据发送完毕!");
byte[] by = new byte[1024];
DatagramPacket dp2 = new DatagramPacket(by, 1024);
System.out.println("端口:" + dp.getPort() + "等待接受数据!");
ds.receive(dp2);
System.out.println("端口:" + dp.getPort() + "接收数据完毕!");
String str2 = new String(dp2.getData() , 0 , dp2.getLength()) + " from " + dp2.getAddress().getHostAddress() + ": " + dp2.getPort();
System.out.println(str2);
}
}
接收方代码:
- 接收方创建的通道需要对应发送方定义的端口(port)。
- 然后创建集装箱对象接受即可。
package UDPtest;
import java.io.IOException;
import java.net.*;
public class UDPreceive {
public static void main(String[] args) throws IOException {
DatagramSocket ds = new DatagramSocket(3000);
byte[] by = new byte[1024];
DatagramPacket dp = new DatagramPacket(by, 1024);
System.out.println("端口3000: 等待接受数据!");
ds.receive(dp);
System.out.println("端口3000:已经收到数据!");
String str = new String(dp.getData(), 0, dp.getLength()) + " from " + dp.getAddress().getHostAddress() + ": " + dp.getPort();
System.out.println(str);
String str2 = "HELLO, WORLD!";
DatagramPacket dp2 = new DatagramPacket(str2.getBytes(), str2.length(), InetAddress.getByName("127.0.0.1"), dp.getPort());
System.out.println("端口:" + dp.getPort() + "正在发送数据!");
ds.send(dp2);
System.out.println("端口:" + dp.getPort() + "发送数据完毕!");
}
}
TCP编程
TCP:Transmission Control Protocol。面向接连的,安全。
TCP编程实现过程:
- 服务器:创建一个ServerSocket,等待连接。
- 客户机:创建一个Socket,连接到服务器。
- 服务器:接收到连接后,创建一个Socket与客户机专线连接。
- 服务器的SocketServer继续等待其他客户机连接。
ServerSocket:服务器码头,要在某个端口上。
Socket:运输通道。
客户端需要绑定服务器的端口和地址。
客户端的输出相当于服务端的输入,反正亦然。
服务端每接待一个客户端,都会启动一个线程对应。
例子:
- 服务器线程创建ServerSocket对象,驻守在8003端口。
- 当接受到客户端的请求时,开始启动线程Worker,并为其建立一个专用的通道。
- 在Worker中建立数据读写通道,获取通道中的数据。
package UDPtest;//文件放在此包中。
import java.io.EOFException;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class TCPTest {
public static void main(String[] args) throws IOException {
try {
ServerSocket s = new ServerSocket(8003);
int i = 0;
while(true) {
Socket ss = s.accept();//等待通道建立。
System.out.println("客人" + ++i + "来了");
new Thread(new Worker(ss)).start();
}
}catch(EOFException e) {
e.printStackTrace();
}
}
}
//Worker代码
package UDPtest;
import java.net.*;
import java.io.*;
class Worker implements Runnable {
Socket s;
public Worker(Socket s) {
this.s = s;
}
public void run() {
try {
System.out.println("服务器已启动!");
InputStream ips = s.getInputStream();
OutputStream ops = s.getOutputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(ips));
DataOutputStream dos = new DataOutputStream(ops);
while (true) {
String strWord = br.readLine();
System.out.println(" client said:" + strWord +":" + strWord.length());
if (strWord.equalsIgnoreCase("quit"))
break;
String strEcho = strWord + " 666";
System.out.println("server said:" + strWord + "---->" + strEcho);
dos.writeBytes(strWord + "---->" + strEcho + System.getProperty("line.separator"));
}
br.close();
dos.close();
s.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
客户端代码:
- 客户端,创建Socket对象,对应服务端的Ip+端口。
- 创建相应的输入输出流,来读写数据。
package UDPtest;
import java.io.IOException;
import java.net.*;
import java.io.*;
public class Client {
public static void main(String[] args) throws UnknownHostException, IOException {
Socket s = new Socket(InetAddress.getByName("127.0.0.1"), 8003);
InputStream ips = s.getInputStream();
OutputStream ops = s.getOutputStream();
BufferedReader brNet = new BufferedReader(new InputStreamReader(ips));
DataOutputStream dos = new DataOutputStream(ops);
BufferedReader brKey = new BufferedReader(new InputStreamReader(System.in));
while(true) {
String word = brKey.readLine();
if(word.equalsIgnoreCase("exit"))
break;
else {
System.out.println("I wanna send" + word);
//写给服务器数据
dos.writeBytes(word + System.getProperty("line.separator"));
//读取服务器的数据
System.out.println("Server said:" + brNet.readLine());
}
}
}
}