网络通信三要素
IP:设备在网络中的地址,也是唯一标识。
端口:应用在设备中的唯一标识。
协议:连接和数据在网络中传输的规则。
·IP


java中的IP类


·端口

·协议
TCP和UDP:传输层协议,编程中使用的主要传输协议。
- UDP协议:无连接,不可靠通信。

- TCP通信:面向连接,可靠通信。
三次握手,四次挥手。相对没有udp效率高

传输时也会返回确认,确保可靠性。
java中使用UDP

只要时DatagramSocket对象都使用UDP建立连接
DatagramSocket用来创建客户端服务端,DatagramPacket用来创建数据包,数据传输时都发送数据包。

客户端发送数据

public class Main {
public static void main(String[] args) throws Exception {
Scanner sc = new Scanner(System.in);
DatagramSocket socket = new DatagramSocket();
byte[] bytes = sc.nextLine().getBytes();
DatagramPacket packet = new DatagramPacket(bytes,bytes.length,InetAddress.getLocalHost(),8800);
socket.send(packet);
System.out.println("发送完毕");
socket.close();
}
}
服务端接收数据

public class server {
public static void main(String[] args) throws Exception {
DatagramSocket socket = new DatagramSocket(8800);
byte[] buffer = new byte[1024 * 64];
DatagramPacket packet = new DatagramPacket(buffer,buffer.length);
socket.receive(packet);
int length = packet.getLength();
System.out.println(new String(buffer, 0, length));
}
}
允许客户端多开


可以实现多发多收,此时不能指定端口,自动分配才不会冲突。
JAVA中使用TCP
使用Socket类即为TCP协议通信。

ServerSocket类用来建立服务端的TCP连接

通过accept方法获得服务端的socket对象以后就可以使用socket进行数据通信了。
使用DataInputStream和DataOutputStream进行通信数据传输比较好用。

读写时客户端和服务端用的数据类型和读写方法都要一一对应。
客户端代码
public class client {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
try(Socket socket = new Socket("localhost",8888);
DataOutputStream output = new DataOutputStream(socket.getOutputStream());) {
while (true) {
System.out.println("talk:");
output.writeUTF(sc.nextLine());
output.flush();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
服务端代码
public class server {
public static void main(String[] args) throws Exception {
ServerSocket serverSocket = new ServerSocket(8888);
while (true) {
Socket socket = serverSocket.accept();
new ServerReaderTheard(socket).start();
}
}
}
public class ServerReaderTheard extends Thread{
private Socket socket;
public ServerReaderTheard(Socket socket){
this.socket = socket;
}
@Override
public void run() {
try(DataInputStream input = new DataInputStream(socket.getInputStream());) {
while (true) {
try {
System.out.println(socket.getRemoteSocketAddress());
System.out.println(input.readUTF());
} catch (IOException e) {
System.out.println(socket.getRemoteSocketAddress()+"离线了");
input.close();
socket.close();
break;
}
}
} catch (IOException e) {
}
}
}
通过创建线程实现多客户端同时通信。
实现简易B/S架构

public class server {
public static void main(String[] args) throws Exception {
ServerSocket serverSocket = new ServerSocket(8888);
while (true) {
Socket socket = serverSocket.accept();
System.out.println(socket.getRemoteSocketAddress()+ "在线");
new ServerReaderTheard(socket).start();
}
}
}
public class ServerReaderTheard extends Thread{
private Socket socket;
public ServerReaderTheard(Socket socket){
this.socket = socket;
}
@Override
public void run() {
try(DataInputStream input = new DataInputStream(socket.getInputStream());
PrintStream output = new PrintStream(socket.getOutputStream())) {
output.println("HTTP/1.1 200 OK");
output.println("Content-type:text/html;charset=UTF-8");
output.println();
output.println("你好");
} catch (IOException e) {
}
}
}
- 每次都创建新线程,使用线程池优化一下
public class server {
public static void main(String[] args) throws Exception {
ServerSocket serverSocket = new ServerSocket(8888);
ThreadPoolExecutor pool = new ThreadPoolExecutor(16,16,0, TimeUnit.SECONDS,new ArrayBlockingQueue<>(8),
Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());
while (true) {
Socket socket = serverSocket.accept();
pool.execute(new ServerReaderTheard(socket));//传的是Runnable对象
System.out.println(socket.getRemoteSocketAddress()+ "在线");
new ServerReaderTheard(socket).start();
}
}
}
231

被折叠的 条评论
为什么被折叠?



