学习Java(88)_基于TCP的聊天程序(二)

基于TCP的聊天程序(一)中进行了改进,双方可以畅快的聊天了,不用再你一句我一句的聊了。
客户端程序
/*
	整体上来说和第一个版本的差别不大,
	就是把读和写用两个线程分开
*/
import java.io.*;
import java.net.*;
class TCPClient_2
{
	public static void main( String[] args )
	{
		Socket s = null;
		DataInputStream dis = null;
		DataOutputStream dos = null;
		
		//获得输入流和输出流对象
		try
		{
			s = new Socket( "127.0.0.1", 6789 ); //向服务端发出链接请求
			dis = new DataInputStream( s.getInputStream() );
			dos = new DataOutputStream( s.getOutputStream() );
			
			//启动接收消息线程
			new ClientReader( dis ).start();
			//启动发出消息线程
			new ClientWriter( dos ).start();
		}
		catch( SocketException e )
		{
			System.out.println( "网络连接失败!" );
			e.printStackTrace();
		}
		catch( IOException e )
		{
			System.out.println( "文件读写失败!" );
			e.printStackTrace();
		}
		catch( Exception e )
		{
			e.printStackTrace();
		}
	}
}
//该类用于接收消息
class ClientReader extends Thread
{
	private DataInputStream dis = null;
	//构造函数,传入dis对象
	public ClientReader( DataInputStream dis )
	{
		this.dis = dis;
	}
	
	public void run()
	{
		String str = null;
		while( true )
		{
			try
			{
				str = dis.readUTF();
				System.out.println( "对方说:"+ str );
				if( str.equalsIgnoreCase( "再见" ) )
				{
					break;
				}
			}
			catch( IOException e )
			{
				System.out.println( "文件读写错误!" );
				e.printStackTrace();
				System.exit( -1 );
			}
		}
	}
}
//该类用于发出消息
class ClientWriter extends Thread
{
	DataOutputStream dos = null;
	
	public ClientWriter( DataOutputStream dos )
	{
		this.dos = dos;
	}
	
	public void run()
	{
		BufferedReader br = new BufferedReader( new InputStreamReader( System.in ) );
		String str = null;
		try
		{
			while( true )
			{
				str = br.readLine();
				dos.writeUTF( str );
				if( str.equalsIgnoreCase( "再见" ) )
				{
					break;
				}
			}	
		}
		catch( IOException e )
		{
			System.out.println( "文件读写错误!" );
			e.printStackTrace();
			System.exit( -1 );
		}
		
	}
}
/*
	在JDK1.8.0_91中运行的结果是:
	============================
	
	============================
	总结:
		开启读和写两个线程之后,读写相互不干扰,就可以畅快的聊天了。
*/
服务端程序
/*
	整体上来说和第一个版本的差别不大,
	就是把读和写用两个线程分开
*/
import java.io.*;
import java.net.*;
class TCPServer_2
{
	public static void main( String[] args )
	{
		ServerSocket ss = null;
		Socket s = null;
		DataInputStream dis = null;
		DataOutputStream dos = null;
		
		try
		{
			ss = new ServerSocket( 6789 );
			s = ss.accept();
			
			dis = new DataInputStream( s.getInputStream() );
			dos = new DataOutputStream( s.getOutputStream() );
			
			//启动接收消息线程
			new ServerReader( dis ).start();
			//启动发出消息线程
			new ServerWriter( dos ).start();
		}
		catch( SocketException e ) //从子类异常到父类异常,依次进行
		{
			System.out.println( "网络连接失败!" );
			e.printStackTrace();
		}
		catch( IOException e )
		{
			System.out.println( "文件读写失败1!" );
			e.printStackTrace();
		}
		catch( Exception e )
		{
			e.printStackTrace();
		}
	}
}
class ServerReader extends Thread
{
	private DataInputStream dis = null;
	//构造函数,传入dis对象
	public ServerReader( DataInputStream dis )
	{
		this.dis = dis;
	}
	
	public void run()
	{
		String str = null;
		while( true )
		{
			try
			{
				str = dis.readUTF();
				System.out.println( "对方说:"+ str );
				if( str.equalsIgnoreCase( "再见" ) )
				{
					break;
				}
			}
			catch( IOException e )
			{
				System.out.println( "文件读写错误!" );
				e.printStackTrace();
				System.exit( -1 );
			}
		}
	}	
}
//该类用于发出消息
class ServerWriter extends Thread
{
	DataOutputStream dos = null;
	
	public ServerWriter( DataOutputStream dos )
	{
		this.dos = dos;
	}
	
	public void run()
	{
		BufferedReader br = new BufferedReader( new InputStreamReader( System.in ) );
		String str = null;
		try
		{
			while( true )
			{
				str = br.readLine();
				dos.writeUTF( str );
				if( str.equalsIgnoreCase( "再见" ) )
				{
					break;
				}
			}	
		}
		catch( IOException e )
		{
			System.out.println( "文件读写错误!" );
			e.printStackTrace();
			System.exit( -1 );
		}
		
	}
}
/*
	在JDK1.8.0_91中运行的结果是:
	============================
	
	============================
	总结:
		开启读和写两个线程之后,读写相互不干扰,就可以畅快的聊天了。
*/


小艾的博客 http://www.aixinyan.me/