java通信—UDP数据报和TCP套接字
一. UDP数据报
注意:udp数据报必须要客户端先给服务器发送信息,然后服务器端才可以回信,因为客户端的ip地址是内网,不是共有网
Sender发信息,Receiver接受信息,并回信
Sender.java
import java.io.IOException;
import java.net.*;
public class Sender {
public static void main(String[] args) {
try{
//设定接受方地址,接收方端口
String ip = "localhost";
InetAddress address = InetAddress.getByName(ip);
int port = 8887;
//消息打包成数据报
String msg = "Hello";
byte[] bytes = msg.getBytes();
DatagramPacket packet = new DatagramPacket(bytes, bytes.length,address,port);
//建立DatagramSocket用来送信
DatagramSocket socket = new DatagramSocket();
//发送信息
socket.send(packet);
//接受对方回信=============================
//1、创建数据报,用于接受服务器端响应数据
byte[] bytes2 = new byte[1024];
DatagramPacket packet2 = new DatagramPacket(bytes2,bytes2.length);
//2、接受服务器响应的数据
socket.receive(packet2);
String reply = new String(bytes2,0,packet2.getLength());
System.out.println("服务器回信说:"+reply);
//4、关闭资源
socket.close();
} catch(UnknownHostException e1) {
e1.printStackTrace();
System.out.println("未知接受地址");
} catch(SocketException e){
e.printStackTrace();
System.out.println("建立DatagramSocket失败");
} catch (IOException e) {
e.printStackTrace();
System.out.println("发送信息失败");
}
}
}
Receiver.java
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
public class Receiver {
public static void main(String[] args) {
try {
//1、创建服务器端DatagramSocket,指定端口
int port = 8887;
DatagramSocket datagramSocket = new DatagramSocket(port);
//2、创建数据报,用于接受客户端发送的数据
byte[] bytes = new byte[1024];
DatagramPacket packet = new DatagramPacket(bytes,bytes.length);
//3、接受客户端发送的数据
datagramSocket.receive(packet);//此方法在接受数据报之前会一致阻塞
//4.读取数据
String msg = new String(bytes,0,packet.getLength());
System.out.println("收到客户端的信息:"+msg);
//============向客户端回送数据=============================
//1、定义客户端的地址、端口号、数据
InetAddress address = packet.getAddress();
int clientPort = packet.getPort();
String result = "收到";
byte[] bytes2 = result.getBytes();
//2、创建数据报,包含响应的数据信息
DatagramPacket packet2 = new DatagramPacket(bytes2,bytes2.length,address,clientPort);
//3、响应客户端
datagramSocket.send(packet2);
//4、关闭资源
datagramSocket.close();
} catch (SocketException e) {
e.printStackTrace();
System.out.println("建立DatagramSocket失败");
} catch (IOException e) {
e.printStackTrace();
System.out.println("回信失败");
}
}
}
局域网内A和B之间互相发送消息,注意仅限于局域网内
A.java
import java.awt.Event;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Scanner;
import javax.swing.*;
public class A extends JFrame implements ActionListener {
int portSend = 6666;
int portReceive = 8888;
InetAddress sendAddr;
JScrollPane p;
JTextArea show;
JTextField input;
JButton send;
public A(){
try {
sendAddr = InetAddress.getByName("127.0.0.1");
} catch (UnknownHostException e) {
System.out.println("URL未知");
e.printStackTrace();
}
this.setLayout(null);
show = new JTextArea(5,20);
p = new JScrollPane(show);
this.add(p);
p.setBounds(20,20,360,250);
input = new JTextField(5);
this.add(input);
input.setBounds(20,280,270,30);
input.addActionListener(this);
send = new JButton("发送");
this.add(send);
send.setBounds(300,278,80,30);
send.addActionListener(this);
this.setBounds(100,50,420,380);
this.setVisible(true);
this.setTitle("聊天者A");
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public void actionPerformed(ActionEvent e) {
String mess = input.getText();
if(!mess.equals(""))
{
sendMessage(mess);
input.setText("");
}
}
public void sendMessage(String str){ //发送信息的函数
byte [] buffer = new byte[1];
try {
DatagramPacket dataPack = new DatagramPacket(buffer,buffer.length,sendAddr,portSend);
DatagramSocket postman = new DatagramSocket();
buffer = str.getBytes();
dataPack.setData(buffer);
postman.send(dataPack);
} catch(IOException ioe){
System.out.println("发送失败!");
}
System.out.println("已经发送信息:"+str);
show.append("A:"+str+"\n");
}
public static void main(String[] args) {
// TODO Auto-generated method stub
A a = new A();
AReceive receive = a.new AReceive();
Thread receiveData = new Thread(receive);
receiveData.start();
}
//负责接收信息
class AReceive implements Runnable{
public void run() {
// TODO Auto-generated method stub
DatagramPacket pack = null;
DatagramSocket postman = null;
byte [] data = new byte[8192];
try{
pack = new DatagramPacket(data,data.length);
postman = new DatagramSocket(portReceive);
}catch (Exception e){}
while(postman!=null){
try {
postman.receive(pack);
String mess = new String(pack.getData(),0,pack.getLength());
//System.out.println("收到回复:"+mess);
show.append("B:"+mess+"\n");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} //end while
} //end void run
} //end class AReceive
}
B.java
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class B extends JFrame implements ActionListener {
int portSend = 8888;
int portReceive = 6666;
InetAddress sendAddr;
JScrollPane p;
JTextArea show;
JTextField input;
JButton send;
public B(){
try {
sendAddr = InetAddress.getByName("127.0.0.1");
} catch (UnknownHostException e) {
System.out.println("URL未知");
e.printStackTrace();
}
this.setLayout(null);
show = new JTextArea(5,20);
p = new JScrollPane(show);
this.add(p);
p.setBounds(20,20,360,250);
input = new JTextField(5);
this.add(input);
input.setBounds(20,280,270,30);
input.addActionListener(this);
send = new JButton("发送");
this.add(send);
send.setBounds(300,278,80,30);
send.addActionListener(this);
this.setBounds(550,50,420,380);
this.setVisible(true);
this.setTitle("聊天者B");
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public void actionPerformed(ActionEvent e) {
String mess = input.getText();
if(!mess.equals(""))
{
sendMessage(mess);
input.setText("");
}
}
public void sendMessage(String str){ //发送信息的函数
byte mess[] = str.getBytes();
try {
DatagramPacket pack = new DatagramPacket(mess,mess.length,sendAddr,portSend);
DatagramSocket postman = new DatagramSocket();
pack.setData(mess);
postman.send(pack);
postman.close();
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
show.append("B:"+str+"\n");
System.out.println("发送信息:"+str);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
B b = new B();
BReceive br = b.new BReceive();
Thread receive = new Thread(br);
receive.start();
}
class BReceive implements Runnable{
public void run() {
byte data[] = new byte[8192];
DatagramPacket pack = null;
DatagramSocket postman = null;
try {
pack = new DatagramPacket(data, data.length);
postman = new DatagramSocket(portReceive);
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
while(postman!=null){
try {
postman.receive(pack);
String mess = new String(pack.getData(),0,pack.getLength());
System.out.println("收到信息:"+mess);
show.append("A:"+mess+"\n");
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
二. TCP套接字
服务器端与多个客户端之间通信
Server.java
Client.java