TCP协议是传输控制协议,是面向连接的通信协议,具有稳定性高,但是效率低的特点
TCP通信是存在于服务端和客户端之间的,通信之前,服务端和客户端都应先建立起通信“套接字”,即socket接口。位于服务端的称为ServerSocket,位于客户端的称为Socket,二者都位于java.net包。
建立通信socket后,再由各自的socket创建通信通道,即输入输出流(InputStream和OutputStream),数据经过此通道进行传输。
服务端步骤是:创建ServerSocket对象并指定ID和端口---->serverSocket对象开启accept()监听模式,并生成Socket对象---->socket对象创建输入流(InputStream)接收客户端数据----->处理客户端数据------>socket对象创建输出流(OutputStream)向客户反馈信息---->逆向关闭资源
客户端步骤是:创建Socket对象并指定IP和端口---->Socket对象创建输出流(OutputStream)向服务器发送信息---->socket对象创建输入流(InputStream)接收服务端反馈信息----->逆向关闭资源
一、TCP传输字符串
package tcp0; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; /** * 服务器类 * @date 2018年1月27日 下午4:39:30 */ public class ServerLogin { public static void main(String[] args) throws IOException, ClassNotFoundException { // 1.创建ServerSocket对象,指定端口号 ServerSocket serverSocket = new ServerSocket(8000); //2.监听客户端请求 Socket socket = serverSocket.accept(); //3.打开输入流,处理用户请求 InputStream is = socket.getInputStream(); // 字节流 InputStreamReader inputStreamReader = new InputStreamReader(is); // 媒介 BufferedReader bufferedReader = new BufferedReader(inputStreamReader); // 字符流 String info = ""; while ((info = bufferedReader.readLine()) != null) { System.out.println("我是服务器,客户信息是:" + info); } socket.shutdownInput(); // 4.服务器反馈 OutputStream os = socket.getOutputStream(); info = "欢迎登陆"; os.write(info.getBytes()); // 5.关闭资源 os.close(); bufferedReader.close(); inputStreamReader.close(); is.close(); socket.close(); serverSocket.close(); } }
package tcp0; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.Socket; import java.net.UnknownHostException; /** * 客户端类 * @date 2018年1月27日 下午4:50:28 */ public class ClientLogin { public static void main(String[] args) throws UnknownHostException, IOException { // 1.创建socket对象,指定要访问发的IP和端口 Socket socket = new Socket("localhost", 8000); // 2.打开输出流,发送请求 OutputStream os = socket.getOutputStream(); String info = "你好,我是小A"; os.write(info.getBytes()); socket.shutdownOutput(); // 3.接收服务端反馈信息 InputStream is = socket.getInputStream();// 字节流 InputStreamReader inputStreamReader = new InputStreamReader(is);// 媒介 BufferedReader bufferedReader = new BufferedReader(inputStreamReader);// 字符流 info = ""; while ((info = bufferedReader.readLine()) != null) { System.out.println("服务商反馈信息是:" + info); } socket.shutdownInput(); // 4.关闭资源 bufferedReader.close(); inputStreamReader.close(); is.close(); os.close(); socket.close(); } }
二、TCP传输对象
package tcp1; import java.io.Serializable; /** * 实体类,需要序列化 * @date 2018年1月27日 下午6:39:39 */ public class User implements Serializable{ private static final long serialVersionUID = 1L; private String name; private String pwd; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPwd() { return pwd; } public void setPwd(String pwd) { this.pwd = pwd; } public User() {} public User(String name, String pwd) { this.name = name; this.pwd = pwd; } }
package tcp1; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; /** * 服务器类 * @date 2018年1月27日 下午4:39:30 */ public class ServerLogin { public static void main(String[] args) throws IOException, ClassNotFoundException { // 1.创建ServerSocket对象,指定端口号 ServerSocket serverSocket = new ServerSocket(8000); //2.监听客户端请求 Socket socket = serverSocket.accept(); //3.打开输入流,处理用户请求 InputStream is = socket.getInputStream(); ObjectInputStream ois = new ObjectInputStream(is); User user = (User) ois.readObject(); System.out.println("我是服务器,客户信息是:" + user.getName() + " " + user.getPwd()); socket.shutdownInput(); // 4.服务器反馈 OutputStream os = socket.getOutputStream(); String info = "欢迎登陆"; os.write(info.getBytes()); // 5.关闭资源 os.close(); ois.close(); is.close(); socket.close(); serverSocket.close(); } }
package tcp1; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.ObjectOutputStream; import java.io.OutputStream; import java.net.Socket; import java.net.UnknownHostException; /** * 客户端类 * @date 2018年1月27日 下午4:50:28 */ public class ClientLogin { public static void main(String[] args) throws UnknownHostException, IOException { // 1.创建socket对象,指定要访问发的IP和端口 Socket socket = new Socket("localhost", 8000); // 2.打开输出流,发送请求 OutputStream os = socket.getOutputStream(); User user = new User("张三", "123456"); ObjectOutputStream oos = new ObjectOutputStream(os); oos.writeObject(user); socket.shutdownOutput(); // 3.接收服务端反馈信息 InputStream inputStream = socket.getInputStream(); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); String info = ""; while ((info = bufferedReader.readLine()) != null) { System.out.println("服务商反馈信息是:" + info); } socket.shutdownInput(); // 4.关闭资源 bufferedReader.close(); oos.close(); inputStream.close(); os.close(); socket.close(); } }
三、多客户端访问服务端
TCP协议处理多用户访问的方式是采用多线程来处理客户请求的。即服务端仅监听请求,一旦接收到请求则新起一个线程,再由这个线程去处理这个请求。
package tcp2; import java.io.Serializable; public class User implements Serializable{ private static final long serialVersionUID = 1L; private String name; private String pwd; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPwd() { return pwd; } public void setPwd(String pwd) { this.pwd = pwd; } public User() {} public User(String name, String pwd) { this.name = name; this.pwd = pwd; } }
package tcp2; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import java.io.OutputStream; import java.net.Socket; /** * 线程类,负责处理客户端请求 * @date 2018年1月27日 下午5:50:11 */ public class LoginThread extends Thread { Socket socket = null; public LoginThread(Socket socket) { this.socket = socket; } @Override public void run() { InputStream is; ObjectInputStream ois; OutputStream os; try { //3.打开输入流,处理用户请求 is = socket.getInputStream(); ois = new ObjectInputStream(is); User user = (User) ois.readObject(); System.out.println("我是服务器,客户信息是:" + user.getName() + " " + user.getPwd()); socket.shutdownInput(); // 4.服务器反馈 os = socket.getOutputStream(); String info = "欢迎登陆"; os.write(info.getBytes()); // 5.关闭资源 os.close(); ois.close(); is.close(); socket.close(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } }
package tcp2; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; /** * 服务器类 用于接收客户端请求,接收到请求后创建并启动线程去处理请求 * @date 2018年1月27日 下午4:39:30 */ public class ServerLogin { public static void main(String[] args) throws IOException { // 1.创建ServerSocket对象,指定端口号 @SuppressWarnings("resource") ServerSocket serverSocket = new ServerSocket(8000); //2.时刻监听客户端请求 while (true) { Socket socket = serverSocket.accept(); // 创建线程 LoginThread loginThread = new LoginThread(socket); // 启动线程 loginThread.start(); } } }
package tcp2; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.ObjectOutputStream; import java.io.OutputStream; import java.net.Socket; import java.net.UnknownHostException; /** * 客户端类 * @date 2018年1月27日 下午4:50:28 */ public class ClientLogin1 { public static void main(String[] args) throws UnknownHostException, IOException { // 1.创建socket对象,指定要访问发的IP和端口 Socket socket = new Socket("localhost", 8000); // 2.打开输出流,发送请求 OutputStream os = socket.getOutputStream(); User user = new User("张三", "123456"); ObjectOutputStream oos = new ObjectOutputStream(os); oos.writeObject(user); socket.shutdownOutput(); // 3.接收服务端反馈信息 InputStream inputStream = socket.getInputStream(); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); String info = ""; while ((info = bufferedReader.readLine()) != null) { System.out.println("服务商反馈信息是:" + info); } socket.shutdownInput(); // 4.关闭资源 bufferedReader.close(); oos.close(); inputStream.close(); os.close(); socket.close(); } }
package tcp2; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.ObjectOutputStream; import java.io.OutputStream; import java.net.Socket; import java.net.UnknownHostException; /** * 客户端类 * @date 2018年1月27日 下午4:50:28 */ public class ClientLogin2 { public static void main(String[] args) throws UnknownHostException, IOException { // 1.创建socket对象,指定要访问发的IP和端口 Socket socket = new Socket("localhost", 8000); // 2.打开输出流,发送请求 OutputStream os = socket.getOutputStream(); User user = new User("李四", "123456"); ObjectOutputStream oos = new ObjectOutputStream(os); oos.writeObject(user); socket.shutdownOutput(); // 3.接收服务端反馈信息 InputStream inputStream = socket.getInputStream(); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); String info = ""; while ((info = bufferedReader.readLine()) != null) { System.out.println("服务商反馈信息是:" + info); } socket.shutdownInput(); // 4.关闭资源 bufferedReader.close(); oos.close(); inputStream.close(); os.close(); socket.close(); } }