1.Socket
Socket是两台机器之间通信的端点,基于TCP、UDP等协议做了一层封装,是一套系统所提供的的用于进行网络通信的编程接口。
2.UDP通信
不同于TCP的客户端-服务器端通信,UDP只有接收端和发送端,二者地位相同。
UDP通信无需建立连接,根据地址直接发送包,如果对方没有收到,也不会报错。
发送端代码:
package net;
import java.net.*;
public class UdpSender {
public static void main(String[] args) throws Exception {
DatagramSocket datagramSocket = new DatagramSocket();
String s = new String("hello, world!");
InetAddress address = InetAddress.getByName("localhost");
int port = 9999;
DatagramPacket datagramPacket = new DatagramPacket(s.getBytes(), 0, (s.getBytes().length), address, port);
datagramSocket.send(datagramPacket);
datagramSocket.close();
}
}
接收端代码:
package net;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.Socket;
public class UdpReceiver {
public static void main(String[] args) throws Exception {
DatagramSocket socket = new DatagramSocket(9999);
byte[] buffer = new byte[1024];
DatagramPacket p = new DatagramPacket(buffer,0,buffer.length);
socket.receive(p);
System.out.println(p.getAddress().getHostAddress());
System.out.println(new String(p.getData(),0,p.getLength()));
socket.close();
}
}
3.UDP用命令行聊天
发送端:
package net;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.*;
public class D3 {
public static void main(String[] args) throws Exception {
DatagramSocket socket = new DatagramSocket(10000);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
while(true){
String s = bufferedReader.readLine();
byte[] data = s.getBytes();
DatagramPacket packet = new DatagramPacket(data, 0, data.length, new InetSocketAddress("localhost",10001));
socket.send(packet);
if(s.equals("bye")) break;
}
socket.close();
}
}
接收端:
package net;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class D4 {
public static void main(String[] args) throws Exception {
DatagramSocket socket = new DatagramSocket(10001);
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length);
while(true){
socket.receive(packet);
String s = new String(packet.getData(),0,packet.getLength());
System.out.println(s);
if(s.equals("bye")) break;
}
socket.close();
}
}
完成了发送端和接收端的代码并不够,还需要用多线程实现每个用户都可以发送和接收。
package net;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;
public class ChatSender implements Runnable{
DatagramSocket socket;
String fromHostName;
int fromPort;
String toHostName;
int toPort;
public ChatSender( String fromHostName, int fromPort, String toHostName, int toPort) {
try {
this.socket = new DatagramSocket(fromPort);
this.fromHostName = fromHostName;
this.fromPort = fromPort;
this.toHostName = toHostName;
this.toPort = toPort;
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void run() {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
try {
while(true){
String s = bufferedReader.readLine();
byte[] data = s.getBytes();
DatagramPacket packet = new DatagramPacket(data, 0, data.length, new InetSocketAddress(toHostName, toPort));
socket.send(packet);
if(s.equals("bye")) break;
}
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
socket.close();
}
}
}
package net;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class ChatReceiver implements Runnable {
String yourHostName;
int myPort;
DatagramSocket socket;
public ChatReceiver(String yourHostName, int myPort) {
this.yourHostName = yourHostName;
this.myPort = myPort;
try {
this.socket = new DatagramSocket(myPort);
} catch (SocketException e) {
e.printStackTrace();
}
}
@Override
public void run() {
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length);
try {
while(true){
socket.receive(packet);
String s = new String(packet.getData(),0,packet.getLength());
System.out.println(yourHostName + ": " + s);
if(s.equals("bye")) break;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
socket.close();
}
}
}
最后不同的用户分别调用这两个线程
package net;
public class Car {
public static void main(String[] args) {
new Thread(new ChatSender("Car",5556,"localhost",6666)).start();
new Thread(new ChatReceiver("Factory", 5555)).start();
}
}
package net;
public class Factory {
public static void main(String[] args) {
new Thread(new ChatSender("Factory",6665,"localhost",5555)).start();
new Thread(new ChatReceiver("Car", 6666)).start();
}
}
实现效果: