UDP编程
UDP的关键就是 DatagramSocket 和DatagramPacket,将数据打包发送和接收,包发出去以后,不管成功与否,效率高,但安全性低。注意UDP的数据都是字节数组!!
相关操作:不分服务端和客户端,只分发送端和·接收端
//UDP编程之接收方
public class UDPGet {
public static void main(String[] args) throws Exception {
//1.使用DatagramSocket指定端口,创建接收方
DatagramSocket socket = new DatagramSocket(9999);
//2.准备容器并封装成DatagramPacket包裹
byte[] bytes = new byte[1024 * 60];//UDp一个包裹最多能接收60k
DatagramPacket packet = new DatagramPacket(bytes, 0, bytes.length);
//3.阻塞式接收包裹
socket.receive(packet);
//4.分析数据
byte[] data = packet.getData();
int len = packet.getLength();
System.out.println(new String(data, 0,len));
}
}
//UDP发送方
public class UDPPost {
public static void main(String[] args) throws Exception {
//1.使用DatagramSocket指定端口发送
DatagramSocket socket = new DatagramSocket(8888);
//2.准备数据,一定要转化成字节数组
String s="Hello socket";
byte[] bytes = s.getBytes();
//3.使用DatagramPackage将数据打包
DatagramPacket packet = new DatagramPacket(bytes, 0, bytes.length, new InetSocketAddress("localhost", 9999));
//4.使用套接字发送包裹
socket.send(packet);
}
}
用UDP传基本数据类型:
/**
* 使用UDP传基本数据类型*/
public class UDPTypePost {
public static void main(String[] args) throws Exception {
DatagramSocket socket = new DatagramSocket(8888);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
//DataOutputStream可以操作基本数据类型
DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(bos));
dos.writeInt(2);//写入
dos.writeChar('s');//写入
dos.flush();//记得刷新
byte[] bytes = bos.toByteArray();//转化为字节数组
DatagramPacket packet = new DatagramPacket(bytes, 0, bytes.length, new InetSocketAddress("localhost", 9999));
socket.send(packet);
}
}
/**
* 基本数据类型接收方*/
public class UDPTypeGet {
public static void main(String[] args) throws Exception {
DatagramSocket socket = new DatagramSocket(9999);
byte[] bytes = new byte[1024];
DatagramPacket packet = new DatagramPacket(bytes, 0, bytes.length);
socket.receive(packet);
byte[] data = packet.getData();//接收数据字节数组
int len = packet.getLength();
//将数组转化为流数组字节流
ByteArrayInputStream bis = new ByteArrayInputStream(data);
//转化为数据流进行读取
DataInputStream dis = new DataInputStream(bis);
int i = dis.readInt();
char c = dis.readChar();
System.out.println(i+"==>"+c);
}
}
用UDP写个咨询聊天:
只要将方法封装成线程即可,演示:
public class Send implements Runnable {
private DatagramSocket send;
private BufferedReader reader;
//指定自己的IP
private String IP;
//指定发送的IP
private int toIP;
public Send(int port,String IP,int toIP){
this.IP=IP;
this.toIP=toIP;
try {
send=new DatagramSocket(port);
} catch (SocketException e) {
e.printStackTrace();
}
}
public void run() {
while (true){
try {
reader = new BufferedReader(new InputStreamReader(System.in));
String s = reader.readLine();
byte[] bytes = s.getBytes();
//将数据打包并指定发送地点
DatagramPacket packet = new DatagramPacket(bytes, 0, bytes.length, new InetSocketAddress(this.IP, this.toIP));
send.send(packet);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public class GetMsg implements Runnable {
private DatagramSocket socket;
//指定发送者的姓名
private String name;
public GetMsg(int port,String name){
this.name=name;
try {
socket=new DatagramSocket(port);
} catch (SocketException e) {
e.printStackTrace();
}
}
@Override
public void run() {
while (true){
//创造一个容器接收消息
byte[] bytes = new byte[1024];
DatagramPacket packet = new DatagramPacket(bytes, 0, bytes.length);
try {
//接收消息
socket.receive(packet);
byte[] data = packet.getData();
int len = packet.getLength();
String s = new String(data, 0, len);
System.out.println(name+":"+s);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
创建两个聊天的实体类:
public class Student {
public static void main(String[] args) {
new Thread(new Send(8888,"localhost",9999)).start();
new Thread(new GetMsg(7777,"老师")).start();
}
}
public class Teacher {
public static void main(String[] args) {
new Thread(new GetMsg(9999,"学生")).start();
new Thread(new Send(6666,"localhost",7777)).start();
}
}
即可实现聊天。
TCP编程,要区分服务端和客户端,服务端使用ServerSocket创建服务端的端口,并用accept阻塞式接收客户端的连接:
演示:
服务端
public class Server {
public static void main(String[] args) throws IOException {
System.out.println("--------server---------");
//1.创建服务器端口
ServerSocket socket = new ServerSocket(8888);
//2.阻塞式等待连接
Socket client = socket.accept();
System.out.println("一个客户进行了连接");
//3.创建流接收数据
DataInputStream stream = new DataInputStream(client.getInputStream());
String s = stream.readUTF();
System.out.println(s);
}
}
public class Client {
public static void main(String[] args) throws IOException {
System.out.println("-----client----");
//1.使用socket创建客户端,并指定端口
Socket socket = new Socket("localhost", 8888);
//2.创建数据流操作数据,并发送
DataOutputStream stream = new DataOutputStream(socket.getOutputStream());
String s="Hello";
stream.writeUTF(s);
stream.flush();
}
}
用TCP写个登录验证
演示:
登录服务器:
public class loginServer {
public static void main(String[] args) throws IOException {
//创建登录的端口
ServerSocket socket = new ServerSocket(8888);
//用户连接就接收
while(true){
Socket accept = socket.accept();
new Thread(new Chat(accept)).start();
}
}
}
class Chat implements Runnable{
private Socket accept;
public Chat(Socket accept){
this.accept=accept;
}
@Override
public void run() {
System.out.println("一个用户上线了");
try {
//获取数据
InputStream stream= accept.getInputStream();
DataInputStream stream1 = new DataInputStream(stream);
String s = stream1.readUTF();
String s1 = stream1.readUTF();
//分析数据
if(s.equals("jr") && s1.equals("123")){
System.out.println("登录成功");
}else {
System.out.println("用户名密码错误");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
客户端登录:
public class loginClient {
public static void main(String[] args) throws IOException {
Socket socket = new Socket("localhost",8888);
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
System.out.println("请输入你的用户名:");
String s = reader.readLine();
System.out.println("请输入密码:");
String s1 = reader.readLine();
DataOutputStream stream = new DataOutputStream(socket.getOutputStream());
stream.writeUTF(s);
stream.writeUTF(s1);
}
}