千峰JAVA逆战班Day33

Day33

*用Socket传输对象。

package com.qianfeng.am.demo;

import java.io.Serializable;

public class Goods implements Serializable{
	String id;
	String name;
	public Goods() {
		
	}
	public Goods(String id, String name) {
		super();
		this.id = id;
		this.name = name;
	}
	@Override
	public String toString() {
		return "Goods [id=" + id + ", name=" + name + "]";
	}
}

package com.qianfeng.am.demo;

import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class TestObjectStream_Server {

	public static void main(String[] args) {
		try {
			ServerSocket ss = new ServerSocket(8888);
			//·监听客户端是否连接
			Socket server = ss.accept();
			//·对象必须实现Serializable接口
			Goods goods = new Goods("1", "apple");
			//·对象输出流
			ObjectOutputStream oos = new ObjectOutputStream(server.getOutputStream());
			oos.writeObject(goods);
			oos.flush();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

package com.qianfeng.am.demo;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.Socket;
import java.net.UnknownHostException;

public class TestObjectStream_Client {

	public static void main(String[] args) {
		String ip = "127.0.0.1";
		int port = 8888;
		try {
			Socket client = new Socket(ip,port);
			//·对象输入流
			ObjectInputStream ois = new ObjectInputStream(client.getInputStream());
			//·这里用object类接受,用到了多态,如果需要使用goods类里面的属性或者方法需要向下转型
			Object goods = ois.readObject();
			System.out.println(goods);
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}
}

*Scanner和PrintWriter

package com.qianfeng.am.demo2;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.Scanner;

/**
 * @author 吴一凡
 *	Scanner 只是一种输入流的高级包装类,而不仅仅是控制台录入
 *	PrintWriter 是一种输出流的高级包装类,也可以用来进行控制台打印
 */
public class ScannerAndPrintWrite {

	public static void main(String[] args) throws Exception {
		//·我们经常用的控制台录入:
		Scanner input = new Scanner(System.in);//·这里的in才是控制台输入流,而不是scanner
		System.out.println(input.nextLine());
		//·读取文件里的内容
		Scanner scan = new Scanner(new FileInputStream("src\\test.txt"));
		String msg = scan.nextLine();
		System.out.println(msg);
		
		//·printwriter进行控制台打印
		PrintWriter pw = new PrintWriter(System.out);
		pw.print(msg);
		pw.flush();//·将缓冲区的内容打印到控制台
		scan.close();
	}
}

*在Socket中使用Scanner和PrintWriter



package com.qianfeng.am.demo1;
//·客户端
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;

public class TestClient {
	static String ip = "";
	static int port = 8888;
	public static void main(String[] args) {
		try {
			Socket client = new Socket(ip,port);
			//·字节流的高级包装类
			Scanner scan = new Scanner(client.getInputStream());
			PrintWriter pw = new PrintWriter(client.getOutputStream());
			//·写入消息给服务器
			pw.println("你好");
			pw.flush();
			//·读取服务器传过来的消息
			System.out.println(scan.nextLine());
			client.close();
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

*基于socket的单线程的简单登录注册(不完善)

package com.qianfeng.pm.demo1;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

/**
 * @author 吴一凡
 *	服务器端
 */
public class LoginServer {

	public static void main(String[] args) {

		try {
			ServerSocket ss = new ServerSocket(8888);
			System.out.println("服务器启动...");
			Socket server;
			Scanner scan;
			PrintWriter pw;
			//·用死循环实现无限次监听
			while(true) {
				server = ss.accept();
				System.out.println("客户端已连接...");
				//·输入输出流
				scan = new Scanner(server.getInputStream());
				pw = new PrintWriter(server.getOutputStream());
				
				while(true) {
					//·传给用户一个信息
					pw.println("请选择你要操作的功能:1登录,2注册,3退出");
					pw.flush();
					
					//·再接受用户一个信息
					String i = scan.nextLine();
					switch (i) {
					case "1":
						login(scan,pw);
						break;
					case "2":
						regist(scan,pw);
						break;
					default:
						break;
					}
				}
			}
			
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}
	//·必须保证输出一次,输入一次
	private static void regist(Scanner scan, PrintWriter pw) {
		pw.println("===欢迎使用注册系统===\n请输入用户名");
		pw.flush();
		scan.nextLine();
		pw.println("请输入密码");
		pw.flush();
		scan.nextLine();
		pw.println("恭喜你注册成功");
		pw.flush();
		scan.nextLine();
	}

	private static void login(Scanner scan, PrintWriter pw) {
		pw.println("===欢迎使用登录系统===\n请输入用户名");
		pw.flush();
		scan.nextLine();
		pw.println("请输入密码");
		pw.flush();
		scan.nextLine();
		pw.println("恭喜你登录成功");
		pw.flush();
		scan.nextLine();
	}
}

package com.qianfeng.pm.demo1;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;

/**
 * @author 吴一凡
 *	用户登录端
 */
public class LoginClient {

	public static void main(String[] args) {
		//·用户输入账号密码,发送给服务器端,服务器返回登录成功或者失败
		String ip = "127.0.0.1";
		int port = 8888;
		try {
			Socket client = new Socket(ip, port);
			//·输入输出流
			Scanner scan = new Scanner(client.getInputStream());
			PrintWriter pw = new PrintWriter(client.getOutputStream());
			
			while(true) {
				//·因为是单线程,所以只能先接受一次信息,再发送一条信息,如此往复
				System.out.println(scan.nextLine());
				//·从键盘录入一条信息,发送
				Scanner input = new Scanner(System.in);
				pw.println(input.nextLine());
				pw.flush();
			}
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}	
	}
}

由于是单线程服务器端和客户端的输入流和输入要一一对应(一个输入另一端就必须是输出)
*基于Socket的简单的多线程多人聊天室

package com.qianfeng.pm.demo2;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Scanner;
import java.util.Set;

public class TestServer {
	//·用hashset 因为不需要排序
	static Set<Socket> set = new HashSet<Socket>();
	public static void main(String[] args) {
		try {
			ServerSocket ss = new ServerSocket(8888);
			while(true) {
				Socket server = ss.accept();
				set.add(server);
				new Students(server).start();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

//·服务器每连接一个客户端,就开一个线程
class Students extends Thread{
	Socket socket;
	//·将当前socket对象作为实参传入,然后进行输入和输出
	public Students(Socket socket) {
		super();
		this.socket = socket;
	}
	
	@Override
	public void run() {
		try {
			Scanner scan = new Scanner(socket.getInputStream());
			while(true) {
				String msg = scan.nextLine();
				//·如果用户输入quit,则退出
				if("quit".equals(msg)) {
					break;
				}
				//·将客户端输入的这条信息,群发给所有人
				this.printAll(msg);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	//·群发消息方法
	private void printAll(String msg) throws IOException {
		PrintWriter pw;
		//·Socket的集合的迭代器
		Iterator<Socket> it = TestServer.set.iterator();
		while(it.hasNext()) {
			//·每个Socket对象都实例化一个输出流
			pw = new PrintWriter(it.next().getOutputStream());
			pw.println(msg);pw.flush();
		}
	}
}

package com.qianfeng.pm.demo2;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;

/**
 * @author 吴一凡
 *	客户端
 */	
public class TestClient {

	public static void main(String[] args) {
		String ip = "127.0.0.1";
		int port = 8888;
		try {
			Socket client = new Socket(ip, port);
			//·将发送消息和接受消息分成两个线程
			new ReaderThread(client).start();
			new WriterThread(client).start();
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
//·接受消息的线程
class ReaderThread extends Thread {
	Socket client;

	public ReaderThread(Socket client) {
		super();
		this.client = client;
	}

	@Override
	public void run() {
		Scanner scan;
			try {
				scan = new Scanner(client.getInputStream());
				while (true) {
					while (scan.hasNext()) {
						System.out.println(scan.nextLine());
					} 
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

//·发送信息线程
class WriterThread extends Thread {
	Socket client;

	public WriterThread(Socket client) {
		super();
		this.client = client;
	}

	@Override
	public void run() {
		try {
			PrintWriter pw = new PrintWriter(client.getOutputStream());
			while(true) {
				Scanner input = new Scanner(System.in);
				pw.println(input.nextLine());
				pw.flush();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}


iterThread extends Thread {
	Socket client;

	public WriterThread(Socket client) {
		super();
		this.client = client;
	}

	@Override
	public void run() {
		try {
			PrintWriter pw = new PrintWriter(client.getOutputStream());
			while(true) {
				Scanner input = new Scanner(System.in);
				pw.println(input.nextLine());
				pw.flush();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值