网络编程的要素
IP和端口号
网络通信协议
TCP
客户端
- 连接服务器socket
- 发送消息
public static void main(String[] args) throws IOException {
//创建一个socket连接
Socket socket = new Socket(InetAddress.getByName("localhost"), 9000);
//创建一个输出流
OutputStream os = socket.getOutputStream();
//读取文件
FileInputStream fis = new FileInputStream(new File("old.png"));
//写出文件
byte [] buffer = new byte[1024];
int len;
while ((len = fis.read(buffer)) != -1) {
os.write(buffer, 0, len);
}
//关闭资源
fis.close();
os.close();
socket.close();
}
服务端
- 建立服务的端口 ServerSocket
- 等待用户的连接 accept
- 接收用户的消息
public static void main(String[] args) throws IOException {
//创建服务
ServerSocket serverSocket = new ServerSocket(9000);
//监听客户端的连接 阻塞式监听,会一直等待客户端连接
Socket socket = serverSocket.accept();
//获取输入流
InputStream is = socket.getInputStream();
//文件输出
FileOutputStream fos = new FileOutputStream(new File("new.png"));
byte[] buffer = new byte[1024];
int len;
while ((len = is.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
//关闭资源
fos.close();
is.close();
socket.close();
serverSocket.close();
}
UDP
客户端
public static void main(String[] args) throws IOException{
//建立一个socket
DatagramSocket socket = new DatagramSocket();
//创建一个需要发送的包
String data = "Hello,server!";
InetAddress localhost = InetAddress.getByName("localhost");
int port = 9090;
DatagramPacket packet = new DatagramPacket(data.getBytes(), 0, data.getBytes().length, localhost, port);
//发送包
socket.send(packet);
//关闭流
socket.close();
}
服务端
public static void main(String[] args) throws IOException {
//开放端口
DatagramSocket socket = new DatagramSocket(9090);
//接收数据包
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length);
socket.receive(packet); //阻塞接收
System.out.println(new String(packet.getData(), 0, packet.getLength()));
//关闭连接
socket.close();
}
利用UDP编写简单的聊天通信
分别实现两个线程接口,一个一直发信息,一个一直接收信息。
发送线程
import java.io.*;
import java.net.*;
public class SendThread implements Runnable {
private InetAddress ip;
private int port;
private String role;
private DatagramSocket socket = null;
private DatagramPacket packet = null;
private BufferedReader reader = null;
@Override
public void run() {
while (true) {
try {
String data = reader.readLine();
byte[] datas = (this.role + ":" + data).getBytes();
packet = new DatagramPacket(datas, 0, datas.length, this.ip, this.port);
socket.send(packet);
if (data.equals("bye")) {
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
socket.close();
}
public SendThread (String ip, int port, String role) {
//创建一个socket连接
try {
this.ip = InetAddress.getByName(ip);
this.port = port;
this.role = role;
socket = new DatagramSocket();
reader = new BufferedReader(new InputStreamReader(System.in));
} catch (SocketException e) {
e.printStackTrace();
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
}
接收线程
import java.io.IOException;
import java.net.*;
public class ReceiveThread implements Runnable {
private int port;
private DatagramSocket socket = null;
private DatagramPacket packet = null;
@Override
public void run() {
while (true) {
//准备接收包裹
byte[] buffer = new byte[1024];
packet = new DatagramPacket(buffer, 0, buffer.length);
try {
socket.receive(packet); //阻塞接收
} catch (IOException e) {
e.printStackTrace();
}
String data = new String(packet.getData(), 0, packet.getLength());
System.out.println(data);
if (data.equals("bye")) {
break;
}
}
socket.close();
}
public ReceiveThread (int port) {
this.port = port;
try {
socket = new DatagramSocket(port);
} catch (SocketException e) {
e.printStackTrace();
}
}
}
通信
//两个客户端分别创建两个线程,就可实现通信了
//老师端
new Thread(new SendThread("localhost", 9000, "老师")).start();
new Thread(new ReceiveThread(9090)).start();
//学生端
new Thread(new SendThread("localhost", 9090, "学生")).start();
new Thread(new ReceiveThread(9000)).start();