欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java: TCP协议socket编程

程序员文章站 2024-03-22 19:00:40
...

一、服务器端

1. 创建ServerSocket对象,监听port端口

private int port =8008;//服务器监听窗口
private ServerSocket serverSocket;//定义服务器套接字

public TCPServer() throws IOException{
    serverSocket =new ServerSocket(port);
    System.out.println("服务器启动,监听"+port+"端口...");
}

2. 定义输入输出流方法

private PrintWriter getWriter(Socket socket) throws IOException{
    //获得输出流缓冲区的地址
    OutputStream socketOut=socket.getOutputStream();

    //网络流写出需要使用flush,这里在printWriter构造方法直接设置为自动flush
    return new PrintWriter(new OutputStreamWriter(socketOut,"utf-8"),true);
}

private BufferedReader getReader(Socket socket) throws IOException{
    //获得输入流缓冲区的地址
    InputStream socketIn=socket.getInputStream();
    return new BufferedReader(new InputStreamReader(socketIn,"utf-8"));
}

3. 服务器核心

通过死循环来让服务器不断运行,通过ServerSocket.accept()方法建立连接。

//单客户版本,每次只能与一个用户建立通信连接
public void Service(){
    while (true){
        Socket socket=null;
        try {
            //此处程序阻塞,监听并等待用户发起连接,有连接请求就生成一个套接字
            socket=serverSocket.accept();

            //本地服务器控制台显示客户连接的用户信息
            System.out.println("New connection accepted:"+socket.getInetAddress());
            BufferedReader br=getReader(socket);//字符串输入流
            PrintWriter pw=getWriter(socket);//字符串输出流
            pw.println("来自服务器消息:欢迎使用本服务!");
    
            String msg=null;
            //此处程序阻塞,每次从输入流中读入一行字符串
            while ((msg=br.readLine())!=null){
                //如果用户发送信息为”bye“,就结束通信
                if(msg.equals("bye")){
                    pw.println("来自服务器消息:服务器断开连接,结束服务!");
                    System.out.println("客户端离开!");
                    break;
                }
                pw.println("来自服务器消息:"+msg);
            }
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            try {
                if (socket!=null)
                    socket.close();//关闭socket连接以及相关的输入输出流
            } catch (IOException e){
                e.printStackTrace();
            }
        }
    }
}

二、客户端

1. 构造方法创建客户端Socket对象,实现输入输出流

private Socket socket;

private PrintWriter pw;
private BufferedReader br;

public TCPClient(String ip, String port) throws IOException{
    //主动向服务器发起连接,实现TCP三次握手
    //不成功则抛出错误,由调用者处理错误
    socket =new Socket(ip,Integer.parseInt(port));

    //得到网络流输出字节流地址,并封装成网络输出字符流
    OutputStream socketOut=socket.getOutputStream();
    //参数true表示自动flush数据
    pw=new PrintWriter(new OutputStreamWriter(socketOut,"utf-8"),true);

    //得到网络输入字节流地址,并封装成网络输入字符流
    InputStream socketIn=socket.getInputStream();
    br=new BufferedReader(new InputStreamReader(socketIn,"utf-8"));
}

2. 实现网络通信发送和接收方法

public void send(String msg){
    //输出字符流,由socket调用系统底层函数,经网卡发送字节流
    pw.println(msg);
}

public String receive(){
    String msg=null;
    try {
        //从网络输入字符流中读取信息,每次只能接受一行信息
        //不够一行时(无行结束符),该语句阻塞
        //直到条件满足,程序往下运行
        msg=br.readLine();
    }catch (IOException e){
        e.printStackTrace();
    }
    return msg;
}

3. 定义关闭连接方法

public void close(){
    try {
        if (socket!=null){
            socket.close();
        }
    }catch (IOException e){
        e.printStackTrace();
    }
}