- 计算机传输层的网络通信 的实质 是分布式的进程之间的通信。 通常分为TCP 和UDP ,前者面向连接,后者非连接、不可靠。
- Java中对两个协议都有支持,Java为TCP提供了服务端的ServerSocket类和客户端的Socket类 ,服务端通过 ServerSocket类提供的accept() 来返回一个Socket对象,形成了 端到端之间通信的桥梁,通过这个桥梁可以获取 InputStream和OutputStream对象操作流进行通信。 总之,Socket是原进程和目的进程之间的一条传输连接。
- Java为 UDP协议提供了DatagramSocket类和 DatagramPacket类来实现UDP的传输。
Java的套接字编程实例:
两个类,一个是服务端的类ServerTCP ,一个是客户端的类ClientTCP。
服务端ServerTCP主要实现 :
1)打开4000端口
2)循环等待并阻塞直到有客户端进程连接到4000端口
3) 分别用两个线程获取inputStream和outputStream,来从客户端读取信息、向客户端写入信息。
客户端ClientTCP主要实现:
1) 创建一个连接到localhost的4000端口的一个Socket
2) 启动两个线程分别获取inputStream和outputStream,来从服务端读取信息、向服务端写入信息。
具体代码:
ServerTCP类:
package com.ServerClient.Inhancement;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerTCP {
public static void main(String[] args) throws Exception {
ServerSocket ss = new ServerSocket(4000);
//循环等待并阻塞直到有客户端进程连接到4000端口,当一个客户端进程连接到获取Socket后,循环等待下一个客户端进程
while (true) {
Socket socket = ss.accept();
//分别用两个线程获取inputStream和outputStream,来从客户端读取信息、向客户端写入信息。
Thread thOutput = new ThreadOutput(socket);
Thread thInput = new ThreadInput(socket);
thOutput.start();
thInput.start();
}
}
}
class ThreadOutput extends Thread {
private Socket socket;
public ThreadOutput(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try {
OutputStream os = socket.getOutputStream();
while (true) {
BufferedReader br = new BufferedReader(new InputStreamReader(
System.in));
String str = br.readLine();
os.write(str.getBytes());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
class ThreadInput extends Thread {
private Socket socket;
public ThreadInput(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try {
InputStream is = socket.getInputStream();
while (true) {
// byte[] buffer = new byte[2048];
// int length = 0;
// while (-1 != (length = is.read(buffer, 0, buffer.length))) {
// String str = new String(buffer, 0, length);
// System.out.println(str);
// }
byte[] buffer = new byte[2048];
int length = is.read(buffer);
System.out.println(new String(buffer, 0, length));
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
客户端ClientTCP类:
package com.ServerClient.Inhancement;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
public class ClientTCP {
public static void main(String[] args) throws Exception {
// 创建一个连接到localhost的4000端口的一个Socket
Socket socket = new Socket("127.0.0.1", 4000);
// 启动两个线程分别获取inputStream和outputStream,来从服务端读取信息、向服务端写入信息。
new ThreadOutput1(socket).start();
new ThreadInput1(socket).start();
}
}
// 该线程负责 从Socket中获得OutputStream流,来向输出流里写信息。
class ThreadOutput1 extends Thread {
private Socket socket;
public ThreadOutput1(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try {
OutputStream os = socket.getOutputStream();
while (true) {
//字符流里 套字节流,system.in是inputStream类型
BufferedReader br = new BufferedReader(new InputStreamReader(
System.in));
String line = br.readLine();
os.write(line.getBytes());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
该线程负责 从Socket中获得InputStream流,从输入流里读取信息。
class ThreadInput1 extends Thread {
private Socket socket;
public ThreadInput1(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try {
InputStream is = socket.getInputStream();
while (true) {
byte[] buffer = new byte[2048];
int length = is.read(buffer);
System.out.println(new String(buffer, 0, length));
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
注意,先运行服务器程序,让其处于等待客户端状态。再运行客户端程序,连接服务端.
在windows cmd上运行两个类,效果如下:
实现了 两端 的通信。