Java - TCP程序的实现

1.TCP程序 - C/S

需要使用到两个类,来编写TCP的C/S程序:
	1.	ServerSocket	搭建服务器,连接客户端
	2.	Socket			搭建客户端,连接服务器
两方使用Socket(套接字,通信端点)进行交流

明确一点,在进行网络编程时,一定是先有服务器,客户端再去连服务器。以后写肯定都有两个Demo(两个main线程),一个是连服务器的,一个是连客户端的。

1.1ServerSocket

1.	用于创建服务器,创建完毕以后,会绑定一个端口号;
2.	然后此服务器可以等待客户端连接;
3.	每连接一个客户端,服务器就会得到一个新的Socket对象,用于跟客户端进行通信。

ServiceSocket类的常用构造方法:
	ServerSocket(int port);//传入指定的端口号port
	
创建一个基于TCP/IP协议的服务器,并绑定指定的端口号,
注意:参数port的范围是:0-65535,建议(1025-65535)

ServerSocket的构造方法

构造器描述
ServerSocket()创建未绑定服务的 套接字
ServerSocket(int port)创建绑定到指定端口的服务器 套接字
ServerSocket(int port,int backlog)创建服务器套接字 并 使用指定的待办事项将其绑定到指定的本地端口
ServerSocket(int port,int backlog,InetAddress bindAddr)创建具有指定端口的服务器,监听backlog和要绑定的本地IP地址

方法很多,有需求可以查看API,常用方法有如下

Soket accept();
	等待客户端连接,
	此方法会导致线程阻塞,
	直到一个新的客户端连接成功,return Socket对象后,线程继续执行

void close();
	释放占用的端口,关闭服务器。就会执行四次挥手操作,稳稳地关闭服务器
变量和类型方法描述
Socketaccept()侦听对此套接字的连接并接受它
voidclose()关闭此套接字
InetAddressgetInetAdress()返回此服务器套接字的本地地址
booleanisClosed()返回ServerSocket的关闭状态

1.2Socket类

是两台计算机之间的通信的端点,是网络驱动提供给应用程序的一种接口,一套标准,一种机制。

常用构造方法:
	Socket(String ip,it port);
		创建一个 套接字,并连接指定ip和端口号的 服务器
		参数1.	服务器ip地址
		参数2.	服务器软件的端口号

连接靠两个Demo实现,先创建服务器端,后创建客户端

//服务器
public class Demo {
    public static void main(String[] args) throws IOException {
        //搭建服务器,写入端口号
        ServerSocket serverSocket = new ServerSocket(55533);
        //等待客户端连接,会阻塞,直到一个客户端连接成功
        Socket socket = serverSocket.accept();
        System.out.println("服务器程序执行结束");
    }
}

必须先运行以上代码后,运行下面代码才能连接

//客户端
public class ClientDemo {
    public static void main(String[] args) throws IOException {
        //本机的IP地址默认为 127.0.0.1
        Socket socket = new Socket("127.0.0.1",55533);
    }
}

Socket类的常用方法

1.OutputStream getOutputStream();
	返回的是,指向通信的另一端点的输出流
	
2.InputStream getInputSream();
	返回的是,指向通信的另一端点的输入流
	
3.void close();
	关闭 套接字	
	
注意:
	1.	在网络编程时,获取输入流的操作,对于客户端与服务器来说是相对的
	2.	客户端的输入流,输入的是服务器的输出流 输出的内容
	3.	客户端的输出流,输出的是服务器的输入流,
	
	所以,在使用时,需要注意以下一点规则:
		客户端与服务器获取流的顺序必须是相反的,只能是一端收一段发,不同两端都发/收,否则会卡在这;
		但是可以选择多线程进行,一个接收一个发送同时将进行。
		
		例如:客户端先得到了输入流,那服务器端必须先获取输出流
		
使用最多的还是getInputStream()/getOutputStream()方法
变量和类型方法描述
voidclose()
InputStreamgetInputStream()返回套接字的输入流
OutputStreamgetOutputStream()返回此套接字的输出流
intgetPort()返回此套接字的远程端口号
booleanisBound()返回套接字的绑定状态
booleanisClosed()返回套接字的连接状态
booleanisConnected()返回套接字的连接状态

代码演示:

//服务器端
public class Demo {
    public static void main(String[] args) throws IOException {
        //搭建服务器,ServerSocket()需要传入 端口号(0-65565)
        ServerSocket serverSocket = new ServerSocket(55533);
        System.out.println("服务器启动完毕");
        //等待客户端连接,会阻塞,直到一个客户端连接成功
        Socket socket = serverSocket.accept();
        System.out.println("一个客户端连接了");

        //获取一个输出流
        OutputStream os = socket.getOutputStream();	
        //把输出流转换为打印流,转换为打印流是为了可以输入一串字符
        PrintStream ps = new PrintStream(os);
        //给客户端发送消息
        ps.println("客户端你好");

        //接收
        InputStream is = socket.getInputStream();
        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        String txet = br.readLine();
        System.out.println("服务器端接收的信息:"+txet);
        
        System.out.println("服务器程序执行结束");
    }
}
//客户端
public class ClientDemo {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket("127.0.0.1",55533);
        InputStream is = socket.getInputStream();
        //使用BufferedReader接收可以一次接收一行
        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        String text = br.readLine();
        System.out.println("客户端接收到消息:"+text);

        //发送
        OutputStream os = socket.getOutputStream();
        PrintStream ps = new PrintStream(os);
        ps.println("服务器你好");
    }
}

1.3在服务器中加入多线程

在连接以后进行的操作必须执行完毕才能再回去连接客户端,比如sleep(),只有sleep()执行完毕以后服务器端才能连接客户端

服务器能同时服务多个客户端怎么办,使用循环等待客户端连接必不可少。注意客户端与服务器端必须是一端输入一端接收的机制

//就不进行接收演示了,就是接 收,交替执行
public class Demo {
    public static void main(String[] args) throws IOException {
        //搭建服务器
        ServerSocket serverSocket = new ServerSocket(55533);
        System.out.println("服务器启动完毕");

        while (true) {
            //等待客户端连接,会阻塞,直到一个客户端连接成功
            //服务器可以抗住很多的客户端
            Socket socket = serverSocket.accept();
            // 启动一个子线程与客户端进行交互,无限循环就无限启动子线程,主线程就能一直等待客户端连接
            // 提高服务器的处理多个客户端的能力
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        InputStream is = socket.getInputStream();
                        OutputStream os = socket.getOutputStream();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
            System.out.println("一个客户端连接了");
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值