赞
踩
传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议,
如果使用了 WireShark 工具,可以看到一次TCP连接建立时的整个过程。
单向通信中,一方固定为信息发送方,另外一方则固定为信息的接收方。
服务端即为信息的接收方。
使用 ServerSocket 类创建服务端,并将服务的端口设置为 9527;
serverSocket.accept() 方法用于监听对 9527 端口的连接,该方法为阻塞式方法,当接收到数据后,程序才会继续向下执行,否则一直处于等待状态;
当接收到数据后,因是使用字节流传输,这里使用 使用 InputStreamReader 的转换流将字节数据转换为字符串,并使用 BufferedReader 进行读取和输出;
当服务端接收到客户端的请求后,需要向客户端发出响应数据,使用 PrintWriter 发送响应报文,需要使用 flush() 方法,将消息发出;
当客户端发出的消息为“再见”时,服务端即退出通信,关闭服务。
- import java.io.*;
- import java.net.ServerSocket;
- import java.net.Socket;
-
- public class Server {
- public static void main(String[] args) {
- System.out.println("服务器启动!");
- try {
- ServerSocket serverSocket = new ServerSocket(9527);
- Socket socket = serverSocket.accept();
- BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
- PrintWriter pw = new PrintWriter(socket.getOutputStream());
- System.out.println("接收客户端消息");
-
- while (true){
- String in = br.readLine();
- System.out.println("接收到客户端发来的请求:" + in);
- if("再见".equals(in)){
- break;
- }
- pw.print(in + "回报");
- pw.flush();
- }
- } catch (IOException e) {
- System.out.println("服务启动失败!");
- e.printStackTrace();
- }
- }
- }

启动后,服务端输出为:
服务器启动!
客户端即为信息的发送方。
Socket("localhost", 9527)
和端口为 9527 的服务建立通信;- import java.io.BufferedReader;
- import java.io.IOException;
- import java.io.InputStreamReader;
- import java.io.PrintWriter;
- import java.net.Socket;
- import java.util.Scanner;
-
- public class Client {
- public static void main(String[] args) {
- try {
- Socket socket = new Socket("localhost", 9527);
- //读取输入流
- BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
- //获取输出流
- PrintWriter pw = new PrintWriter(socket.getOutputStream());
- //从键盘获取输入
- Scanner scanner = new Scanner(System.in);
-
- while (true){
- //从控制台获取向服务端发送的消息
- String next = scanner.next();
- pw.println(next);
- pw.flush();
-
- String s = br.readLine();
- System.out.println("收到服务器响应:" + s);
-
- if("再见".equals(next)){
- break;
- }
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }

启动客户端后,并在客户端的控制台输入“你好”,观察服务端和客户端的控制台
在客户端的控制台输入“再见”,观察服务端和客户端的控制台
双向通信中,双方都可以既是信息的发送方,也可以是信息的接收方。
在服务端设置发消息和收消息。
在服务端也使用了 Scanner ,用来接收控制台输入,并将其发送给客户端。
- import java.io.BufferedReader;
- import java.io.InputStreamReader;
- import java.io.PrintWriter;
- import java.net.ServerSocket;
- import java.net.Socket;
- import java.util.Scanner;
-
- public class Server {
- public static void main(String[] args) {
- try{
- ServerSocket serverSocket = new ServerSocket(9528);
- Socket socket = serverSocket.accept();
- //获取客户端请求
- BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
- //获取键盘输入
- Scanner scanner = new Scanner(System.in);
- //发送消息到客户端
- PrintWriter pw = new PrintWriter(socket.getOutputStream());
-
- while (true){
- String input = br.readLine();
- System.out.println("收到客户端请求: " + input);
- String output = scanner.nextLine();
-
- pw.println(output);
- pw.flush();
-
- if("再见".equals(input)){
- break;
- }
- }
- }catch (Exception e){
- e.printStackTrace();
- System.out.println("服务启动失败!");
- }
- }
- }

在客户端设置发消息和收消息
- import java.io.BufferedReader;
- import java.io.InputStreamReader;
- import java.io.PrintWriter;
- import java.net.Socket;
- import java.util.Scanner;
-
- public class Client {
- public static void main(String[] args) {
- try{
- Socket socket = new Socket("127.0.0.1", 9528);
- //获取服务端响应
- BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
- //获取客户端用户输入
- Scanner scanner = new Scanner(System.in);
- //向服务端发送请求
- PrintWriter pw = new PrintWriter(socket.getOutputStream());
- System.out.println("准备接收请求……");
- while (true){
- String output = scanner.next();
- pw.println(output);
- pw.flush();
-
- String input = br.readLine();
- System.out.println("来自服务端的响应: " + input);
- if("再见".equals(output)){
- break;
- }
- }
- }catch (Exception e){
- e.printStackTrace();
- }
- }
- }

启动服务端及客户端,并在控制台输入内容:
存在的问题:
这样的通信,需要客户端发一次消息 -》 服务端回一次消息,如果客户端同时发送两条消息,就会导致消息不同步。
比如下边的情况:
这个问题可以先思考下,应该如何解决,后边将会给出解决方案。
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。