Socket编程(在控制台模拟聊天功能)

@

服务器端

(1) 创建ServerSocket对象,绑定监听端口;

(2) 通过accept()方法监听客户端请求;

(3) 连接建立后,通过输入流读取客户端发送的请求信息;

(4) 通过输出流向客户端发送相应信息;

(5) 关闭响应资源。
客户端

(1) 创建Socket对象,指明需要连接的服务器地址和端口;

(2) 连接建立后,通过输出流向服务器端发送请求信息;

(3) 通过输入流获取服务器端返回的响应信息;

(4) 关闭响应资源。
具体代码实现:

TCP简单示例

服务器:

public class SocketServerOne {
    public static void main(String[] args) {
        ServerSocket serverSocket = null;
        Socket socket = null;
        BufferedReader bufferedReader = null;
        PrintWriter printWriter = null;
        try {
            //实例化ServerSocket
            serverSocket=new ServerSocket(8888);
            //调用accept方法,启动监听,该方法在客户端发送信息之前,一直阻塞(一直等待)
            System.out.println("服务器端已经启动。。。");
            socket = serverSocket.accept();
            //服务器接收信息
            //返回此套接字的输入流,输入流里面放的就是客户端发送过来的信息
            //InputStreamReader的作用把字节流转换为字符流
            //BufferedReader套接缓冲流,目的用来提高读写效率
            bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            //调用readLine()方法得到字符串
            String s = bufferedReader.readLine();
            //打印
            System.out.println("客户端说:"+s);
            //服务器发送信息
            printWriter = new PrintWriter(socket.getOutputStream());
            printWriter.println("你好客户端,你发送的信息我收到了");
            //清空管道
            printWriter.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                bufferedReader.close();
                socket.close();
                serverSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

客户端:

public class SocketClientOne {
    public static void main(String[] args) {
        Socket socket=null;
        PrintWriter printWriter = null;
 
 
        try {
            //实例化Socket对象,通过链接的IP和端口号进行实例化
            socket=new Socket("127.0.0.1",8888);
            //客户端发送信息
            //通过PrintWriter向套接字输出流里面写入信息
            printWriter = new PrintWriter(socket.getOutputStream());
            //调用printLine方法写入信息
            printWriter.println("你好,服务器22");
            //刷新管道
            printWriter.flush();
            System.out.println("信息发送完毕。。。");
            //客户端接收信息
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            //调用readLine方法得到字符串
            String s=bufferedReader.readLine();
            //打印
            System.out.println("服务器端说:"+s);
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                printWriter.close();
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

TCP模拟聊天

服务器:

public class SocketServerTwo {
    public static void main(String[] args) {
        ServerSocket serverSocket=null;
        Socket socket = null;
        BufferedReader bufferedReader = null;
        PrintWriter printWriter = null;
        try {
            serverSocket=new ServerSocket(7777);
            System.out.println("服务器启动。。。");
            //启动监听
            socket = serverSocket.accept();
            //接收相关方法
             bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            //发送的相关的方法
            printWriter = new PrintWriter(socket.getOutputStream());
            //控制台扫描类
            Scanner scanner=new Scanner(System.in);
            //循环接收信息或者扫描控制台发送信息
            while(true){
                //读取
                String s = bufferedReader.readLine();
                System.out.println("客户端说:"+s);
                if(s.contains("借钱")){
                    printWriter.println("你被拉入黑名单。。");
                    printWriter.flush();
                    break;
                }
                System.out.println("请输入:");
                String next = scanner.next();
                //发送
                printWriter.println(next);
                //清空
                printWriter.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                printWriter.close();
                bufferedReader.close();
                socket.close();
                serverSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

客户端:

public class SocketClientTwo {
    public static void main(String[] args) {
        Socket socket=null;
        BufferedReader bufferedReader = null;
        PrintWriter printWriter = null;
        try {
           socket=new Socket("127.0.0.1",7777);
            //接收相关方法
            bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            //发送的相关的方法
            printWriter = new PrintWriter(socket.getOutputStream());
            //控制台扫描类
            Scanner scanner=new Scanner(System.in);
            //循环
            while(true){
                System.out.println("请输入:");
                //发送
                String next = scanner.next();
                printWriter.println(next);
                printWriter.flush();
                //接收
                String s = bufferedReader.readLine();
                System.out.println("服务器说:"+s);
                if(s.contains("黑名单")){
                    printWriter.println("借钱");
                    printWriter.flush();
                    break;
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                printWriter.close();
                bufferedReader.close();
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

UDP简单示例

UDP程序原理

客户端:
1) 创建客户端 DatagramSocket 类 + 指定的发送端口
2) 准备数据 以字节数组的形式
3) 打包 DatagramPacket+服务器端的地址和端口
4) 发送
5) 释放资源
服务器端
1) 创建服务端 DatagramSocket 类 + 指定的接收端口
2) 准备接收数据的容器 以字节数组的形式封装为DatagramPacket
3) 包 接收数据
4) 分析
5) 释放资源
服务器端:

public class UDPServer {
    public static void main(String[] args) {
        DatagramSocket datagramSocket=null;
        try {
            //实例化DatagramSocket用于发送或者接收数据
            datagramSocket=new DatagramSocket();
            //声明发送字符串
            String str="hello qy88";
            //实例化数据报包类,数据的载体
            DatagramPacket datagramPacket=new DatagramPacket(str.getBytes(),str.getBytes().length,
                    InetAddress.getByName("localhost"),6666);
            //发送
            datagramSocket.send(datagramPacket);
            System.out.println("发送完毕。。。");
        } catch (SocketException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            datagramSocket.close();
        }
    }
}

客户端:

public class UDPClient {
    public static void main(String[] args) {
        DatagramSocket datagramSocket=null;
        try {
            datagramSocket=new DatagramSocket(6666);
            byte[] by=new byte[1024];
            //数据的载体,会把接收到的数据放入缓冲数组,并且记录下放入数组的长度
            DatagramPacket datagramPacket=new DatagramPacket(by,1024);
            System.out.println("接收端已经启动。。。");
            //接收
            datagramSocket.receive(datagramPacket);
            //组装数据,打印
            String str=new String(by,0,datagramPacket.getLength());
            System.out.println(str);
        } catch (SocketException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

UDP模拟聊天

服务端

package com.qq.common;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.util.Scanner;

public class ServerThread implements Runnable {
    private int port;
    public ServerThread(int port) {
        super();
        this.port=port;
    }
    @Override
    public void run() {
        @SuppressWarnings("resource")
        Scanner scanner=new Scanner(System.in);
        //服务端(接收方)的端口
        DatagramSocket ds = null;
        try {
            ds = new DatagramSocket(port);
        } catch (SocketException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("服务端已经启动!");
        while(true) {
            //准备收数据
            byte[] b=new byte[1024];
            DatagramPacket dp=new DatagramPacket(b, b.length);
            //开始收  收到的是字节数组
            try {
                ds.receive(dp);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println(new String(dp.getData(),0,dp.getLength()));
            System.out.println("对方IP地址:"+dp.getAddress()+"  "+"端口:"+dp.getPort());
            
            //发数据
            //准备数据
            String s=scanner.next();
            byte[] buf=s.getBytes();
            //打包
            DatagramPacket dp2=new DatagramPacket(buf, buf.length,dp.getAddress(),dp.getPort());
            try {
                ds.send(dp2);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            if("bye".equals(s)) {
                break;
            }   
        }
        ds.close(); 
    }   
}
package com.qq.common;

public class Test {
    public static void main(String[] args) {
        ServerThread server=new ServerThread(8886);
        Thread thread=new Thread(server);
        thread.start();
    }
}

客户端

package common;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Scanner;

public class ClientThread implements Runnable{
    private int port;
    public ClientThread(int port) {
        this.port=port;
    }
    @Override
    public void run() {
        @SuppressWarnings("resource")
        Scanner scanner=new Scanner(System.in);
        //发数据
        DatagramSocket ds = null;
        try {
            ds = new DatagramSocket(9999);
        } catch (SocketException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }//客户端的端口号是9999
        System.out.println("客户端已经启动,开始聊天吧?!");
        while(true) {
            String s=scanner.next();
            byte[] buf=s.getBytes();
            DatagramPacket dp = null;
            try {
                dp = new DatagramPacket(buf, buf.length,InetAddress.getByName("127.0.0.1"),port);
            } catch (UnknownHostException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            try {
                ds.send(dp);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            byte[] buf2=new byte[1024];
            DatagramPacket dp2=new DatagramPacket(buf2, buf2.length);
            try {
                ds.receive(dp2);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
            System.out.println("对方IP地址:"+dp2.getAddress()+"  "+"端口:"+dp2.getPort());
            String str=new String(dp2.getData(),0,dp2.getLength());
            System.out.println(str);
            if("bye".equals(str)) {
                break;
            }
        }
        ds.close();
    }
}
package common;

public class Test {
public static void main(String[] args) {
    ClientThread client=new ClientThread(8886);
    Thread t=new Thread(client);
    t.start();
}
}

TCP和UDP是Java网络编程中的传输方式。TCP提供两台计算机之间可靠无差错的数据传输,但资源消耗较大,性能和效率较低;UDP不保证可靠数据的传输,但资源消耗小,性能和效率较高。在实际网络编程中建议根据系统的特点和需要,具体选择合适的方式

猜你喜欢

转载自www.cnblogs.com/fantongxue/p/12443284.html
今日推荐