1.网络编程概述
-
网络编程就是在一定的协议下,实现两台设备之间通信的程序
2.TCP协议
-
在计算机网络中,提前约定好的通信方式,被称为网络通信协议,它对数据的传输方式、传输速率、传输步骤等做了统一规定,通信双方必须同时遵守才能完成数据交换
-
TCP通信协议时Internet最基本、最广泛的协议,它定义了计算机如何连入互联网,以及数据如何在它们之间传输的标准
-
TCP协议能够实现两台计算机之间的数据交互,通信的双方,要严格分为客户端(Client)和服务端(Server)
-
两方通信时步骤:
-
服务端程序,需要事先启动,等待客户端连接
-
客户端主动连接服务端,连接成功才能通信,服务端不可以主动连接客户端
-
-
在java中,提供了两个类用于实现TCP通信协议
-
客户端:java.net.Socket类表示,创建Socket对象,向服务器发送连接请求,服务端做出响应,两者建立连接开始通信
-
服务端:java.net.ServerSocket类表示。创建ServerSocket对象,相当于开启一个连接,并等待客户端的连接
-
3.TCP通信
package com.jxd.socket;
import jdk.internal.util.xml.impl.Input;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
/**
* @author Ming WanBao
* 客户端
*/
public class Client {
public static void main(String[] args) throws Exception {
//1.创建Socket对象,绑定服务器的IP地址和端口号
Socket socket = new Socket("127.0.0.1", 8888);
//2.获取网络字节输出流对象
OutputStream os = socket.getOutputStream();
//3.向服务器发送数据
os.write("你好,服务器".getBytes());
//4.获取网络字节输入流对象
InputStream is = socket.getInputStream();
byte[] bytes = new byte[2048];
int len = is.read(bytes);
System.out.println(new String(bytes, 0, len));
//5.关闭资源
socket.close();
}
}
package com.jxd.socket;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
* @author Ming WanBao
* 服务端
*/
public class Server {
public static void main(String[] args) throws Exception {
//1.创建服务端对象,并指明端口号
ServerSocket serverSocket = new ServerSocket(8888);
//2.获取到请求的客户端对象
Socket socket = serverSocket.accept();
//3.获取网络字节输入流对象
InputStream is = socket.getInputStream();
//4.读取客户端发送来的数据
byte[] bytes = new byte[2048];
int len = is.read(bytes);
System.out.println(new String(bytes,0, len));
//5.获取网络字节输出流对象
OutputStream os = socket.getOutputStream();
os.write("收到,谢谢".getBytes());
serverSocket.close();
}
}
4.加入多线程
package com.jxd.socket;
import jdk.internal.util.xml.impl.Input;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Scanner;
/**
* @author Ming WanBao
* 修改客户端,主线程主要负责读取键盘输入并发送给服务器端
*/
public class Client {
public static void main(String[] args) throws Exception {
//1.创建Socket对象,绑定服务器的IP地址和端口号
Socket socket = new Socket("127.0.0.1", 8888);
//创建子线程
Thread thread = new Thread(new ClientThread(socket));
//启动子线程,专门负责读取客户端发送来的数据
thread.start();
//以下为输出
//获取输出流
PrintStream ps = new PrintStream(socket.getOutputStream());
Scanner input = new Scanner(System.in);
//不断地读取键盘的输入
String content = null;
while (true) {
if ((content = input.next()) != null) {
//写入输出流
ps.println(content);
}
}
//5.关闭资源
}
}
package com.jxd.socket;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
/**
* @author Ming WanBao
* 修改服务端,不断接收客户端的信息并将信息返回
*/
public class Server {
public static void main(String[] args) throws Exception {
//1.创建服务端对象,并指明端口号
ServerSocket serverSocket = new ServerSocket(8888);
//2.先接收客户端请求
Socket socket = serverSocket.accept();
//为输入流创建缓冲区
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//不断的读取客户端发送来的消息
while (true) {
String content = null;
if ((content = br.readLine()) != null) {
System.out.println(content);
//并将接收到的内容写回客户端
PrintStream ps = new PrintStream(socket.getOutputStream());
ps.println(content);
}
}
}
}
package com.jxd.socket;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Socket;
/**
* @author Ming WanBao
*/
//创建客户端专门用于读取通信内容的线程类
public class ClientThread implements Runnable{
private Socket socket;
//为输入流创建缓冲区
private BufferedReader br;
public ClientThread(Socket socket) throws IOException {
this.socket = socket;
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
}
@Override
public void run() {
String content;
//不断的读取socket输入流中的内容,并打印输出
while(true) {
try {
if ((content = br.readLine()) != null) {
System.out.println(content);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
5.多人聊天
-
群聊时,必须明确服务器概念,所有的客户端都是给服务器发送消息,服务器再把消息发送给所有的客户端,以达到群聊的效果
-
客户端和客户端不直接通信
-
如果同时有多个客户端连接服务器,那么服务器会针对每一个客户端各自创建一个Socket负责与之通信
-
针对每个客户端的通信,都需要单独创建线程来负责,在服务端,需要使用list集合存储所有用于和客户端通信的socket