Java网络编程学习复习总结(四)-2021.06.03

TCP编程
需求:完成网络登录功能:
用户输入用户名和密码,服务器给出登录成功或登录失败的提示
分析:使用基于TCP协议的SOCKET网络编程实现
TCP协议基于请求-响应模式
在网络通信中,第一次主动发起通讯的程序被称作客户端Client程序
第一次通讯中等待连接的程序被称作服务器端Server程序
利用IO流实现数据的传输

在这里插入图片描述
TCP/IP通信连接的简单过程:

位于A计算机上的TCP/IP软件向B计算机发送包含端口号的消息,B计算机的TCP/IP软件接收该消息,并进行检查,查看是否有它知道的程序正在该端口上接收消息。如果有,他就将该消息交给这个程序。

要使程序有效地运行,就必须有一个客户端和一个服务器。

TCP编程详细步骤:
服务器:创建ServerSocket,在指定端口监听并处理请求
客户端:创建Socket,向服务器发送请求

服务器端:
1.创建ServerSocket(int port)对象
2.在Socket上监听客户端的连接请求
3.阻塞、等待连接的建立----建立连接
4.接收并处理请求信息----服务请求
5.将处理结果返回给客户端----服务相应
6.关闭流和Socket对象

客户端
1.创建Socket(String host,int port)对象
2.向服务器发送连接请求----建立连接
3.向服务器发送服务请求----服务请求
4.接收服务结果----服务响应
5.关闭流和Socket对象

类 ServerSocket
此类实现服务器套接字。服务器套接字等待请求通过网络传入。它基于该请求执行某些操作,然后可能向请求者返回结果。

服务器套接字一次可以与一个套接字连接,如果多台客户机同时提出连接请求,服务器套接字会将请求连接的客户机存入列队中,然后从中取出一个套接字,与服务器新建的套接字连接起来,若请求连接数大于最大容纳数,则多出的连接请求被拒绝。列队的最大容纳数默认大小是50.

服务器套接字的实际工作由 SocketImpl 类的实例执行。应用程序可以更改创建套接字实现的套接字工厂来配置它自身,从而创建适合本地防火墙的套接字。

调用ServerSocket类的accept()方法,会返回一个和客户端Socket对象相连接的Socket对象。服务器端的Socket对象使用getOutputStream()方法获得的输出流,将指向客户端Socket对象使用getlnputStream()方法获得的那个输入流;同样,服务器端的Socket对象使用getlnputStream()方法获得的输入流,将指向客户端Socket对象使用getOutputStream()方法获得的那个输出流。也就是说,当服务器向输出流写入信息时,客户端通过相应的输入流就能读取,反之亦然。
在这里插入图片描述
在这里插入图片描述
类 Socket
此类实现客户端套接字(也可以就叫“套接字”)。套接字是两台机器间通信的端点。

套接字的实际工作由 SocketImpl 类的实例执行。应用程序通过更改创建套接字实现的套接字工厂可以配置它自身,以创建适合本地防火墙的套接字。

在这里插入图片描述
在这里插入图片描述
查看下面程序
Server

package com.sxt.tcp;

import java.io.DataInputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 熟悉流程
 * 创建服务器
 * 1、指定端口 使用ServerSocket创建服务器
 * 2、阻塞式等待连接 accept
 * 3、操作: 输入输出流操作
 * 4、释放资源
 */
public class Server {

	public static void main(String[] args) throws IOException {
		System.out.println("-----Server-----");
		// 1、指定端口 使用ServerSocket创建服务器
		ServerSocket server =new ServerSocket(8888);
		// 2、阻塞式等待连接 accept
		Socket  client =server.accept(); 
		System.out.println("一个客户端建立了连接");
		// 3、操作: 输入输出流操作
		DataInputStream dis =new DataInputStream(client.getInputStream());
		String data =dis.readUTF();
		System.out.println(data);
		// 4、释放资源 
		dis.close();
		client.close();
		
		server.close();
	}

}

Client

package com.sxt.tcp;

import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

/**
 * 熟悉流程
 * 创建客户端
 * 1、建立连接: 使用Socket创建客户端 +服务的地址和端口
 * 2、操作: 输入输出流操作
 * 3、释放资源
 */
public class Client {

	public static void main(String[] args) throws UnknownHostException, IOException {
		System.out.println("-----Client-----");
		//1、建立连接: 使用Socket创建客户端 +服务的地址和端口
		Socket client =new Socket("localhost",8888);
		//2、操作: 输入输出流操作
		DataOutputStream dos =new DataOutputStream(client.getOutputStream());
		String data ="hello";
		dos.writeUTF(data);
		dos.flush();
		//3、释放资源 
		dos.close();
		client.close();
	}

}

再看下面的程序
Client

package com.NetworkCommunication;

import javax.swing.*;
import javax.swing.border.BevelBorder;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;


public class TCPClient extends JFrame {
    private PrintWriter printWriter;
    Socket socket;
    Container container;
    private JTextArea jTextArea = new JTextArea();  //创建JTextArea()对象
    private JTextField jTextField = new JTextField();//创建JTextField()对象

    public TCPClient(String title){
        super(title);//构造方法
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        container = this.getContentPane();           //实例化对象
        final JScrollPane jScrollPane = new JScrollPane();
        jScrollPane.setBorder(new BevelBorder(BevelBorder.RAISED));
        getContentPane().add(jScrollPane,BorderLayout.CENTER);
        jScrollPane.setViewportView(jTextArea);
        container.add(jTextField,"South");//将文本框放在窗体下面
        jTextField.addActionListener(new ActionListener(){
            //绑定事件
            public void actionPerformed(ActionEvent e){
                printWriter.println(jTextField.getText());  //将文本框中的信息写入流
                jTextArea.append(jTextField.getText()+'\n');
                jTextArea.setSelectionEnd(jTextArea.getText().length());
                jTextField.setText("");                     //将文本框清空
            }
        });

    }

    public void connect(){
        jTextArea.append("尝试连接\n");
        try {
            socket = new Socket("localhost",8988);
            printWriter= new PrintWriter(socket.getOutputStream(),true);
            jTextArea.append("完成连接\n");
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public static void main(String[] args) {
        TCPClient tcpClient = new TCPClient("向服务器发送数据");
        tcpClient.setSize(200,200);
        tcpClient.setVisible(true);
        tcpClient.connect();

    }
}

Server

package com.NetworkCommunication;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

public class TCPServer {
    private BufferedReader bufferedReader;
    private ServerSocket serverSocket;
    Socket socket;

    public void getServer(){
        try {
            serverSocket = new ServerSocket(8988);//实例化ServerSocket对象
            System.out.println("服务器套接字已经创建成功");
            while (true){
                System.out.println("等待客户机的连接");
                socket = serverSocket.accept(); //实例化Socket对象
                bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                getClientMessage();//调用getClientMessage()方法
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void getClientMessage(){
        try {
            while (true) {              //如果套接字是连接状态
                System.out.println("客户机:" + bufferedReader.readLine());//获得客户端信息
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            if(bufferedReader != null) {
                bufferedReader.close();//关闭流
            }
            if(socket!= null){
                socket.close();
            }


        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public static void main(String[] args) {
        TCPServer tcpServer = new TCPServer();
        tcpServer.getServer();
    }
}

TCP:单向通信Socket之服务器端

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
 
/**
 * 最简单的服务器端代码
 * @author Administrator
 */
public class BasicSocketServer {
    public static void main(String[] args) {
        Socket socket = null;
        BufferedWriter bw = null;
        try {
            // 建立服务器端套接字:指定监听的接口
            ServerSocket serverSocket = new ServerSocket(8888);
            System.out.println("服务端建立监听");
            // 监听,等待客户端请求,并愿意接收连接
            socket = serverSocket.accept();
            // 获取socket的输出流,并使用缓冲流进行包装
            bw = new BufferedWriter(new     
                                    OutputStreamWriter(socket.getOutputStream()));
            // 向客户端发送反馈信息
            bw.write("hhhh");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭流及socket连接
            if (bw != null) {
                try {
                    bw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

TCP:单向通信Socket之客户端

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.Socket;
/**
 * 最简单的Socket客户端
 * @author Administrator
 */
public class BasicSocketClient {
    public static void main(String[] args) {
        Socket socket = null;
        BufferedReader br = null;
        try {
            /*
             * 创建Scoket对象:指定要连接的服务器的IP和端口而不是自己机器的
             * 端口。发送端口是随机的。
             */
            socket = new Socket(InetAddress.getLocalHost(), 8888);
            //获取scoket的输入流,并使用缓冲流进行包装
            br = new BufferedReader(new  
                                   InputStreamReader(socket.getInputStream()));
            //接收服务器端发送的信息
            System.out.println(br.readLine());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭流及socket连接
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

TCP:双向通信Socket之服务器端

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
 
public class Server {
    public static void main(String[] args){
        Socket socket = null;
        BufferedReader in = null;
        BufferedWriter out = null;
        BufferedReader br = null;
        try {
            //创建服务器端套接字:指定监听端口
            ServerSocket server = new ServerSocket(8888);
            //监听客户端的连接
            socket = server.accept();
            //获取socket的输入输出流接收和发送信息
            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            out = new BufferedWriter(new 
                                   OutputStreamWriter(socket.getOutputStream()));
            br = new BufferedReader(new InputStreamReader(System.in));
            while (true) {
                //接收客户端发送的信息
                String str = in.readLine();
                System.out.println("客户端说:" + str);
                String str2 = "";
                //如果客户端发送的是“end”则终止连接 
                if (str.equals("end")){
                    break;
                }
                //否则,发送反馈信息
                str2 = br.readLine(); // 读到\n为止,因此一定要输入换行符!
                out.write(str2 + "\n");
                out.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //关闭资源
            if(in != null){
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(out != null){
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(br != null){
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(socket != null){
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

TCP:双向通信Socket之客户端

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
 
public class Client {
    public static void main(String[] args) {
        Socket socket = null;
        BufferedReader in = null;
        BufferedWriter out = null;
        BufferedReader wt = null;
        try {
            //创建Socket对象,指定服务器端的IP与端口
            socket = new Socket(InetAddress.getLocalHost(), 8888);
            //获取scoket的输入输出流接收和发送信息
            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            out = new BufferedWriter(new 
                                   OutputStreamWriter(socket.getOutputStream()));
            wt = new BufferedReader(new InputStreamReader(System.in));
            while (true) {
                //发送信息
                String str = wt.readLine();
                out.write(str + "\n");
                out.flush();
                //如果输入的信息为“end”则终止连接
                if (str.equals("end")) {
                    break;
                }
                //否则,接收并输出服务器端信息
                System.out.println("服务器端说:" + in.readLine());
            }
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭资源
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (wt != null) {
                try {
                    wt.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

上面代码存在的缺陷或注意点
运行时,要先启动服务器端,再启动客户端,才能得到正常的运行效果。但是,上面这个程序,必须按照安排好的顺序,服务器和客户端一问一答!不够灵活!!可以使用多线程实现更加灵活的双向通讯!!
服务器端:一个线程专门发送消息,一个线程专门接收消息。
客户端:一个线程专门发送消息,一个线程专门接收消息。

TCP:聊天室之客户端

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
 
public class ChatClient {
    public static void main(String[] args) {
        Socket socket = null;
        BufferedReader in = null;
        try {
            socket = new Socket(InetAddress.getByName("127.0.1.1"), 8888);
            // 创建向服务器端发送信息的线程,并启动
            new ClientThread(socket).start();
            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            // main线程负责接收服务器发来的信息
            while (true) {
                System.out.println("服务器说:" + in.readLine());
            }
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (socket != null) {
                    socket.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (in != null) {
                    in.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
 
/**
 * 用于向服务器发送消息
 * 
 * @author Administrator
 *
 */
class ClientThread extends Thread {
    Socket s;
    BufferedWriter out;
    BufferedReader wt;
 
    public ClientThread(Socket s) {
        this.s = s;
        try {
            out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
            wt = new BufferedReader(new InputStreamReader(System.in));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
 
    public void run() {
        try {
            while (true) {
                String str = wt.readLine();
                out.write(str + "\n");
                out.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (wt != null) {
                    wt.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (out != null) {
                    out.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

TCP:聊天室之服务器端

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
 
public class ChatServer {
    public static void main(String[] args) {
        ServerSocket server = null;
        Socket socket = null;
        BufferedReader in = null;
        try {
            server = new ServerSocket(8888);
            socket = server.accept();
            //创建向客户端发送消息的线程,并启动
            new ServerThread(socket).start();
            // main线程负责读取客户端发来的信息
            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            while (true) {
                String str = in.readLine();
                System.out.println("客户端说:" + str);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (socket != null) {
                    socket.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
 
/**
 * 专门向客户端发送消息的线程
 * 
 * @author Administrator
 *
 */
class ServerThread extends Thread {
    Socket ss;
    BufferedWriter out;
    BufferedReader br;
 
    public ServerThread(Socket ss) {
        this.ss = ss;
        try {
            out = new BufferedWriter(new OutputStreamWriter(ss.getOutputStream()));
            br = new BufferedReader(new InputStreamReader(System.in));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
 
    public void run() {
        try {
            while (true) {
                String str2 = br.readLine();
                out.write(str2 + "\n");
                out.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if(out != null){
                out.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(br != null){
                    br.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

在这里插入图片描述
在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

C_Vampirer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值