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. 释放资源
    服务器端
  6. 创建服务端 DatagramSocket 类 + 指定的接收端口
  7. 准备接收数据的容器 以字节数组的形式封装为DatagramPacket
  8. 包 接收数据
  9. 分析
  10. 释放资源
    服务器端:
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不保证可靠数据的传输,但资源消耗小,性能和效率较高。在实际网络编程中建议根据系统的特点和需要,具体选择合适的方式

posted @ 2020-03-08 16:42  你樊不樊  阅读(246)  评论(0编辑  收藏  举报