记录计算机网络基础知识,以及Java网络编程,通过ServerSocket创建服务器,使用accept方法阻塞式获取客户端连接。使用Socket创建客户端。使用IO的形式从客户端向服务器发送数据
一、计算机网络定义
计算机网络是通过通信设备和线路将不同地区的计算机连接起来,实现信息与数据共享。
二、网络模型
OSI七层参考模型如下图所示:
TCP/IP四层协议如下图所示:
三、Java网络编程
在Java语言中,可以通过其分装的类库进行网络编程。如:ServerSocket(服务端)与Socket(客户端)。网络编程的核心要素:如何找到网络中的某台主机,如何实现主机之间高效的数据传输。
主机的IP会区别出一台主机,端口会区别出主机中的程序。
高效数据传输通过传输协议去完成。
第一版代码如下:
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket socket = new ServerSocket(9966);
System.out.println("服务器启动成功!等待客户端连接...");
//监听客户端是否连接服务器。客户端连接后会返回Socket对象。
//如果一直没有客户端连接,则程序将会阻塞,
Socket accept = socket.accept();
System.out.println("客户端连接成功!");
//在网络编程中使用的是IO流的形式进行数据传输
InputStream inputStream = accept.getInputStream();
byte[] data = new byte[100];
int size = inputStream.read(data);
String msg = new String(data,0,size,"UTF-8");
System.out.println(msg);
}
}
public class Client {
public static void main(String[] args) throws IOException {
//创建客户端,基于TCP的,所以会三次握手,检测主机网络是否畅通
Socket socket = new Socket("127.0.0.1", 9966);
//创建输出流,将数据传输到服务器
OutputStream outputStream = socket.getOutputStream();
//write()方法里面接受的是byte数组,可以使用getBytes()方法把字符串转化为byte数组
//getBytes()方法的参数是编码格式
outputStream.write("你好服务器!".getBytes("UTF-8"));
}
}
第二版代码如下:
public class TwoServer {
public static void main(String[] args) throws IOException {
ServerSocket serverSockets = new ServerSocket(9966);
Socket socket = serverSockets.accept();
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
DataInputStream din = new DataInputStream(in);
DataOutputStream dout = new DataOutputStream(out);
Scanner scanner = new Scanner(System.in);
while (true) {
String msg = din.readUTF();
System.out.println("客户端"+socket.getRemoteSocketAddress()+"发来消息:"+msg);
System.out.println("服务端输入:");
String serverMsg = scanner.next();
dout.writeUTF(serverMsg);
}
}
}
public class TwoClient {
public static void main(String[] args) throws IOException {
Socket socket = new Socket("127.0.0.1",9966);
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
DataInputStream din = new DataInputStream(in);
DataOutputStream dout = new DataOutputStream(out);
Scanner scanner = new Scanner(System.in);
while (true){
System.out.println("客户端输入:");
String msg = scanner.next();
dout.writeUTF(msg);
String serverMsg = din.readUTF();
System.out.println("服务端发来消息:"+serverMsg);
}
}
}
第三版代码如下:
public class UdpServer {
public static void main(String[] args) throws IOException {
DatagramSocket datagramSocket = new DatagramSocket(9966);
byte[] bytes = new byte[1024];
DatagramPacket datagramPacket = new DatagramPacket(bytes,bytes.length);
datagramSocket.receive(datagramPacket);
String clientMsg = new String(bytes,0,datagramPacket.getLength());
System.out.println(clientMsg);
}
}
public class UdpClient {
public static void main(String[] args) throws IOException {
DatagramSocket socket = new DatagramSocket();
byte[] bytes = "你好服务端!".getBytes("UTF-8");
DatagramPacket datagramPacket = new DatagramPacket(bytes,bytes.length, InetAddress.getByName("127.0.0.1"),9966);
socket.send(datagramPacket);
}
}
第一版与第二版代码都是使用TCP实现的Socket通信,第三版使用的是UDP实现的Socket通信。
第一版代码实现了客户端与服务端的一次交互。
第二版代码实现了客户端与服务端多次交互,但是由于accept方法与Scanner会阻塞线程,所以交互形式是客户端发起交互,服务端收到交互信息,服务端进行交互,只可以轮流依次交互。
第三版代码使用UDP协议实现了Socket通信,不需要服务端先启动,可以直接发送信息到指定IP地址。
总结
通过ServerSocket创建服务器,使用accept方法阻塞式获取客户端连接。使用Socket创建客户端。使用IO的形式从客户端向服务器发送数据。