java 基于TCP协议的SOCKET的编程和通信-多用户登录

参考文档

https://www.sxt.cn/Java_jQuery_in_action/twelve-tcpsocket.html

参考视频

https://www.bilibili.com/video/BV1ct411n7oG?p=246

1.代码功能

1.实现多用户登录

2.学习重点

1.服务器端使用多线程使得多个客户端可以同时使用
2.封装:服务器端一个客户端一个channel,客户端服务器端都对收发消息进行封装,客户端将从键盘获取输入封装为init()初始化;服务器端对关闭资源封装,run方法里只操作业务逻辑(调用receive后分析数据,调用send返回结果)。

3.客户端代码

1.创建client
2.调用Send类,Receive类里的send,receive方法。
	2.1Send类里包含client,dos等相关的属性,Send构造函数里包含业务逻辑,发送端的初始化,init()里包含console的初始化,send函数里就是单纯的发送消息。
	2.2Receive类与Send类类似,包含client,dis等相关属性,Receive构造函数里包含client,dis的初始化,receive函数里就是单纯的接收消息。
3.关闭client
package com.sxt.tcp;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;

/**
 *模拟登录 多个客户端请求
 * 创建客户端
 * 1.建立连接:使用Socket创建客户端+服务的地址和端口
 * 2.操作:输入输出流操作
 * 3.释放资源
 * @author Yangxiaoxia
 *
 */
public class LoginMultiClient {
	public static void main(String[] args) throws UnknownHostException, IOException {
		System.out.println("-----Client-----");

		//1.建立连接:使用Socket创建客户端+服务的地址和端口
		Socket client=new Socket("localhost",8888);
		//2.操作:输入输出流操作
		new Send(client).send();
		new Receive(client).receive();
		  
		client.close();
	}
	//发送
	static class Send{
		private Socket client;
		private DataOutputStream dos;
		private BufferedReader console;
		private String msg;
		public Send(Socket client) {
		    console =new BufferedReader(new InputStreamReader(System.in));
		    this.msg=init();
		    this.client=client;

			 try {
				dos=new DataOutputStream(client.getOutputStream());
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} 
		}
		private String init() {
			try {
				System.out.print("请输入用户名:");
				String uname=console.readLine();
				System.out.print("请输入密码:");
				String upwd =console.readLine();
				return "uname="+uname+"&"+"upwd="+upwd;
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			return " ";
		}
		public void send( ) {
			try {
				dos.writeUTF(msg);
				dos.flush();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	//接收
	static class Receive{
		private Socket client;
		private DataInputStream dis;
		public Receive(Socket client) {
			this.client=client;
			 try {
				dis=new DataInputStream(client.getInputStream());
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} 
		}
		
		public void receive() { 
			String result;
			try {
				result = dis.readUTF();
				System.out.println(result);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
	}
	
}

4.服务器端代码

1.创建server
2.给参数isRuning,while循环里阻塞式等待连接,给客户端开启多线程
	2.1一个Channel类代表一个客户端,继承Runnable接口,实现抽象方法run,run方法里处理业务逻辑,分析数据,返回结果,Channel类包含client,dis,dos属性 Channel构造函数包含 3个属性的初始化,以及client.close(),释放资源。send,receive,release方法分别是发送数据,接收数据,释放资源。
3.关服务器
package com.sxt.tcp;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

import org.omg.PortableInterceptor.DISCARDING;

/**
 * 模拟登录 多个客户端请求
 * 创建服务器
 * 1.指定端口 使用ServerSocket创建服务器
 * 2.阻塞式等待连接 accept
 * 3.操作:输入输出流操作
 * 4.释放资源
 * @author Yangxiaoxia
 *
 */
public class LoginMultiServer {
	public static void main(String[] args) throws IOException {
		System.out.println("------Server-------");
		 // 1.指定端口 使用ServerSocket创建服务器
		ServerSocket server=new ServerSocket(8888);
		boolean isRuning=true;
		 // 2.阻塞式等待连接 accept
		while(isRuning) {
			Socket client=server.accept();
			System.out.println("一个客户端建立了连接");
			new Thread(new Channel(client)).start();
		}
		server.close();
	}
	//一个channel 就代表一个客户端
	static class Channel implements Runnable{
		private Socket client;
		//输入流
		private DataInputStream dis;
		//输出流
		private DataOutputStream dos;
		public Channel(Socket client) {
			this.client=client;
			try {
				dis = new DataInputStream(client.getInputStream());
				//输出
				dos=new DataOutputStream(client.getOutputStream());
			} catch (IOException e) {	
				// TODO Auto-generated catch block
				e.printStackTrace();
				try {
					client.close();
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
					release();
				}
			} 
		}
		//接收数据 
		private String receive() {
			String datas="";
			try {
				datas = dis.readUTF();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			return datas;
		}
		//释放资源
		private void release() {
			try {
				if(null!=dos) {
					dos.close();
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			try {
				if(null!=dis) {
					dis.close();
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			try { 
				if(null!=client) {
					client.close(); 
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		//发送数据
		private void send(String msg) {
			try {
				dos.writeUTF(msg);
				dos.flush();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
		public void run() {
			 // 3.操作:输入输出流操作 
			String uname=" ";
			String upwd=" ";
			//分析
			String[] dataArray=receive().split("&");
			for(String info:dataArray) {
				String[] userinfo=info.split("=");
				if(userinfo[0].equals("uname")) { 
					System.out.println("你的用户名为:"+userinfo[1]);
					uname=userinfo[1];
				}else if(userinfo[0].equals("upwd")) { 
					System.out.println("你的密码为:"+userinfo[1]);
					upwd=userinfo[1];
				} 
			}

			if(uname.equals("baidu")&& upwd.equals("123456")) {//成功
				send("登陆成功,欢迎回来");
			}else {//失败
				send("用户名或密码错误");
			}
			release();
		}
		
	}
	
}


 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值