Java基础案例教程 第十一章 网络编程 ———11.3 TCP通信

一、基本理论

UDP只有发送端和接收端,不区分客户端和服务器端,计算机之间可以任意地发送数据

TCP是严格区分客户端和服务器端的,在通信时,必须先由客户端去连接服务器端才能实现通信,服务器端不可以主动连接客户端,并且服务器端需要事先启动,等待客户端的连接

 

JDK中提供了两个用于实现TCP程序的类,一个是ServerSocket类,用于表示服务器端,另一个是Socket类,用于表示客户端。

通信时:首先要创建代表服务器端的ServerSocket对象,创建该对象相当于开启一个服务,此服务会等待客户端的连接;

               然后创建代表客户端的Socket对象,使用该对象向服务器端发出连接请求,服务器端响应请求后,两者才建立连接,开始通信

                                      

 

1、ServerSocket

            

ServerSocket对象负责监听某台计算机的某个端口号,在创建ServerSocket对象后,需要继续调用该对象的accept()方法,接收来自客户的请求;

当执行了accept()方法之后,服务器端程序会发生阻塞,直到客户端发出连接请求时,accept()方法才会返回一个Socket对象用于和客户端实现通信,程序才能继续向下执行。

 

2、Socket

            

        

                                       

 

 

二、简单的TCP网络程序

1、Server

1)创建ServerSocket对象,指定端口号

2)调用ServerSocket的accept()方法接收 客户端的请求

3)获取客户端的输出流

4)通过输出流写数据到客户端  或者  通过输入流从客户端读取发来的数据

5)关闭对象释放资源

package cn.itcast.chapter11.example03;

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

public class Server {
    public static void main(String[] args) throws Exception {
        new TCPServer().listen(); // 创建TCPServer对象,并调用listen()方法
    }
}

// TCP服务端
class TCPServer {
    private static final int PORT = 7788; // 定义一个端口号

    public void listen() throws Exception { // 定义一个listen()方法,抛出一个异常
        // 1、创建ServerSocket对象
        ServerSocket serverSocket = new ServerSocket(PORT);
        // 2、调用ServerSocket的accept()方法接收数据
        Socket client = serverSocket.accept();
        // 3、获取客户端的输出流
        OutputStream os = client.getOutputStream();
        System.out.println("开始与客户端交互数据");
        // 4、当客户端连接到服务端时,向客户端输出数据
        os.write(("传智播客欢迎你!").getBytes());
        Thread.sleep(5000); // 模拟执行其他功能占用的时间
        System.out.println("结束与客户端交互数据");
        //5、关闭对象,释放资源
        os.close();
        client.close();
    }
}

 

2、Client

1)创建一个Socket并连接到给出地址和端口号的计算机

2)得到接收数据的流

3)将缓冲区中的数据输出

4)关闭Socket对象,释放资源

package cn.itcast.chapter11.example03;

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

public class Client {
    public static void main(String[] args) throws Exception {
        new TCPClient().connect(); // 创建TCPClient对象,并调用connect()方法
    }
}

// TCP客户端
class TCPClient {
    private static final int PORT = 7788; // 服务端的端口号

    public void connect() throws Exception {
        // 1、创建一个Socket并连接到给出地址和端口号的计算机
        Socket client = new Socket(InetAddress.getLocalHost(), PORT);
        // 2、得到接收数据的流
        InputStream is = client.getInputStream();
        byte[] buf = new byte[1024]; // 定义1024个字节数组的缓冲区
        int len = is.read(buf); // 将数据读到缓冲区中
        // 3、将缓冲区中的数据输出
        System.out.println(new String(buf, 0, len));
        // 4、关闭Socket对象,释放资源
        client.close();
    }
}

 

 

 

三、多线程的TCP网络程序

                                            

package cn.itcast.chapter11.example04;

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

/*
 * 服务器端,多线程版
 * */
public class Server {
    public static void main(String[] args) throws Exception {
        // 1、创建ServerSocket对象,监听指定的端口
        ServerSocket serverSocket = new ServerSocket(7788);

        // 使用while循环不停的接收客户端发送的请求
        while (true) {
            // 2、调用ServerSocket的accept()方法与客户端建立连接
            final Socket client = serverSocket.accept();
            // 内部代码块
            new Thread(new Runnable() {
                @Override
                public void run() {
                    OutputStream os;  // 定义一个输出流对象
                    try {
                        // 3、获取客户端的输出流
                        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();

        }
    }
}


注意:无法识别出是一个客户端多次访问,还是多个客户端同时访问

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值