TCP客户端和服务端

时间:2024-03-16 10:32:29

先写服务端,一定要先执行服务端

package wangluobiancheng;

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

public class Server {
/*
 * TCP通信严格区分客户端和服务器端,在通信时必须先由客户端去连接服务器端才能实现通信,服务器端不能主动连接客户端
 * 并且服务器端程序要先启动,等待客户端的连接
 * ServerSocket类,用于表示服务器端,通信时要先创建代表服务器端的ServerSocket对象,相当于开启一个服务,此服务会等待客户端的连接。
 * Server类,表示客户端,创建Server对象,使用该对象向服务器端发出连接请求,服务器端响应后,客户端再次向服务器端发送确认信息,确认连接
 * ServerSocket()使用该构造方法在创建ServerSocket对象时,并没有绑定端口号,这样的对象创建的服务器端没有监听任何端口,不能直接使用
 * *最常用ServerSocket(int port)可以将其绑定到一个指定的端口号上(参数port就是端口号)。客户端需要指定的端口号来访问服务器端程序
 * ServerSocket(int port,int backlog)可以将其绑定到一个指定的端口号上(参数port就是端口号)。客户端需要指定的端口号来访问服务器端程序,backlog用于指定在
 * 服务器忙时,可以与之保持连接请求的等待客户数量,如果没有指定这个参数,默认为50
 * ServerSocket(int port,int backlog,InetAddress bindAddr)bindAddr用于指定相关的IP地址,该构造方法的使用适用于计算机上有多块网卡和多个IP的情况
 * 使用时可以明确规定ServerSocket在哪块网卡或IP地址上等待客户的连接请求。
 */
    public static void main(String[] args) throws Exception {
//        创建TCPServer对象,并调用listen()方法
        TCPServer tcpss=new TCPServer();
        tcpss.listen();
    }

}

/*//TCP服务端
class TCPServer{
    private static final int PORT = 7788;//定义一个端口号
    public void listen() throws Exception {
//        创建ServerSocket(服务器)对象,指定端口PORT,即7788
        ServerSocket s = new ServerSocket(PORT);
//        Socket accept()该方法用于等待客户端的连接,在客户端连接之前会一直处于阻塞状态,如果有客户端连接,就会返回一个与之对应的Socket对象,就是服务器也会创建一个Socket对象,去和客户端的Socket对象对应
//        调用ServerSocket的accept()方法接受客户端的请求,执行accept()方法之后程序会发生阻塞,直到客户端发出连接请求时,accept()会返回一个与之对应的Socket对象,用于和客户端实现通信
        Socket client = s.accept();
        OutputStream os = client.getOutputStream();//创建输出流对象,向客户端输出数据
        System.out.println("开始与客户端交互数据");
//        当客户端连接到服务端时,向客户端输出数据。("传智博客欢迎你!").getBytes()将定义的字符串转换为字节数组
        os.write( ("传智博客欢迎你!").getBytes() );
        Thread.sleep(5000);//模拟执行其他功能占用的时间
        System.out.println("结束与客户端交互数据");
        os.close();//关闭缓冲区
        client.close();//关闭客户端与服务器的连接
    }
}*/

/*
 * 上面的程序分别实现了服务器端程序和客户端程序,当一个客户端程序请求服务器端时,服务器端就会结束阻塞状态,完成程序的运行
 * 实际上,很多服务器端程序都是允许被多个应用程序访问的,例如门户网站可以被多个用户同时访问,因此服务器都是多线程的
 * 多个客户端访问同一个服务器端,服务器端为每个客户创建一个对应的Socket,并且开启一个新的线程使两个Socket(一个是客户端的,一个是服务器端的)建立专线进行通信
 */
//TCP服务端
class TCPServer{
    private static final int PORT = 7788;//定义一个端口号
    public void listen() throws Exception {
//        创建ServerSocket(服务器)对象,指定端口PORT,即7788
        ServerSocket s = new ServerSocket(PORT);
//        使用while循环不停的接受客户端发送的请求
        while(true) {
//        Socket accept()该方法用于等待客户端的连接,在客户端连接之前会一直处于阻塞状态,如果有客户端连接,就会返回一个与之对应的Socket对象
//        调用ServerSocket的accept()方法接受客户端的请求,执行accept()方法之后程序会发生阻塞,直到客户端发出连接请求时,accept()会返回一个与之对应的Socket对象,用于和客户端实现通信
        Socket client = s.accept();
//        下面的代码用来开启一个新的线程
        new Thread() {
            public void run() {
                OutputStream os;//定义一个输出流对象
                try {
                    os = client.getOutputStream();//获取客户端的输出流
                    System.out.println("开始与客户端交互数据");
                    os.write(("传智播客欢迎您!").getBytes());
                    Thread.sleep(5000);//使线程休眠5000毫秒
                    System.out.println("结束与客户端交互数据");
                    os.close();//关闭输出流
                    client.close();//关闭Socket对象
                }catch(Exception e) {
                    e.printStackTrace();
                }
            }
            }.start();
        }
    }
}

再写客户端。(就是再建一个java文件)

package wangluobiancheng;

import java.io.InputStream;
import java.net.InetAddress;
import java.net.Socket;

public class Client {
/*
 * Socket用于实现TCP客户端程序
 * Socket()该构造方法在创建Socket对象时,并没有指定IP地址和端口号,也就意味着只创建了客户端对象,并没有连接任何服务器。
 * 通过该构造方法创建对象后还需调用connect(SocketAddress endpoint)方法,才能完成与指定服务器端的连接。其中参数endpoint用于封装IP地址和端口号
 */
    public static void main(String[] args) throws Exception {
        TCPClient tcpc = new TCPClient();
        tcpc.connect();//创建TCPClient对象,并调用connect()方法
    }
}
class TCPClient{
    private static final int PORT = 7788;//服务端的端口号
    public void connect() throws Exception {
//        Socket(InetAddress address,int port)该构造方法在创建Socket对象时,指明IP地址和端口号
//        创建一个Socket(客户端)并连接到给出地址和端口号的计算机
        Socket client = new Socket(InetAddress.getLocalHost(),PORT);
        InputStream is = client.getInputStream();//创建输入流对象,client.getInputStream()用来接受服务器发来的数据
//        定义1024个字节数组
        byte[] buf = new byte[1024];
        int len = is.read(buf);//将数据读取到缓冲区
        System.out.println( new String(buf,0,len) );//将缓冲区中的数据打印
//        关闭Socket对象,即关闭连接,释放资源
        client.close();
    }
}

服务器文件执行后

TCP客户端和服务端

客户端执行后

TCP客户端和服务端