一个简单的客户端与服务器端交互

线程与网络IO实现简单客户端与服务端聊天交互
首先在学习了线程和网络IO后,做了一个练习.客户端给服务器端发消息.服务器端回消息给客户端.问题由此而生!


服务器类:

public class ThreadServer {
	/**
	 * 在服务器端也写两个内部类实现读与写的分离
	 * @author 旖析木
	 *
	 */
	private class THDL extends Thread{//读的类
		private Socket socket ;
		
		public THDL(Socket socket) {
			this.socket = socket;//连接当前套接字
		}
		

		@Override
		public void run() {//从写run方法
			DataInputStream in = null;
			try {
				in = new DataInputStream(socket.getInputStream());
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			while(true) {
				String str = null;
				try {
					String msg = in.readUTF();//读取流中消息
					System.out.println("接受到的消息是:"+msg);//打印出来
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
			}
		}
	}
	private class DLTH extends Thread{//写的类
		private Socket socket ;
		
		public DLTH(Socket socket) {
			this.socket = socket;
		}
		

		@Override
		public void run() {
			DataOutputStream out = null;
			try {
				out = new DataOutputStream(socket.getOutputStream());//创建流
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			while(true) {
				String str = null;
				try {
					Scanner sc = new Scanner(System.in);//获取控制台输入 
					//******就是这里出现错误****因为服务器端的进程里面有两个线程,两个线程公用一个System.in就是抢着回复客户端.所以哪个进程运气好就回给哪个进程
					str = sc.nextLine();
					out.writeUTF("回消息:"+str);
					out.flush();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
			}
		}
	}
	public static void main(String[] args) {
		try {
			ServerSocket ss = new ServerSocket(8080);//监听8080端口
			System.out.println("服务器开始监听8080端口");
			while(true) {//用循环实现可以允许多个客户端连接
				Socket socket = ss.accept();//获取到当前连接的客户端
				System.out.println("接受一个客户端连接!来电显示"+socket);
				THDL th = new ThreadServer().new THDL(socket);//绑定socket 调用写的类
				th.start();
				DLTH th2 = new ThreadServer().new DLTH(socket);//绑定socket 调用读的类
				th2.start();
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

客户端类

public class ThreadCiled {
	//写一个内部类用于实现"写"
	private class Xie extends Thread{
		private Socket socket ;//
		
		public Xie(Socket socket) {
			this.socket = socket;//连接当前套接字
		}
		@Override
		public void run() {
			String str = null;
			Scanner sc = new Scanner(System.in);
			do {
			try {
				DataOutputStream out = new DataOutputStream(socket.getOutputStream());
				str = sc.nextLine();//通过控制台获取输入
				out.writeUTF(str);//用writeUTF写入流中
				out.flush();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			}while(true);
			
		}
	}
	//一个内部类实现"读"
	private class Du extends Thread{
		private Socket socket;
		public Du(Socket socket) {
			this.socket = socket;//连接当前套接字进行读
		}
		@Override
		public void run() {
			String str = null;
			DataInputStream in;
			do {
			try {
				in = new DataInputStream(socket.getInputStream());
				str = in.readUTF();//读取传过来流中的数据
				System.out.println(str);//打印出来
				
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}}while(true);
		}
		
	}
	
	public static void main(String[] args){
		String str = null;
		Scanner sc = new Scanner(System.in);
			Socket socket;
			try {
				socket = new Socket("localhost", 8080);//连接本地IP8080端口
				Xie th = new ThreadCiled().new Xie(socket);//Xie线程调用方法实现写的分离
				th.start();
				Du xi = new ThreadCiled().new Du(socket);//Xie线程调用方法实现读的分离
				xi.start();
			} catch (UnknownHostException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
}
}

这里如果运行两个客户端的话,同时给服务器端发消息 会发生服务器端不知道给哪个客户端回消息的情况!!!如同就像是抢这个sc.next()一样.

在这里插入图片描述
出现如此情况,就需要绑定socket来回复!但是目前技术有限,所以日后修改.现在先记录这个问题!

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值