【Socket网络通信】利用TCP/IP协议实现服务端与客户端的双向聊天

服务器:

 

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

/**
 *  @author $KangMiao$
 *  服务端
 * 与TCPTalkClient02.java一起用
 * 利用TCP/IP协议实现服务端与客户端的双向聊天
 * 问题:①当服务端输入quit时 ,我输入的信息客户端接收不到,但可以看到客户端发来的信息。
 * (已解决) 在两个线程中分别关闭相应的流
 */

public class TCPTalkServer02 {
	public void talk() {
		try {
			ServerSocket ss = new ServerSocket(8888);  
			System.out.println("聊天服务器开启···");
			Socket s = null;
			while ((s = ss.accept()) != null) {
				System.out.println(s.getInetAddress()+"朋友来访中-----");
				ThreadTalk tt = new ThreadTalk(s);
				tt.start();
			}

		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		TCPTalkServer02 talk = new TCPTalkServer02();
		talk.talk();
	}
}

class ThreadTalk extends Thread {
	private Socket s;
	private BufferedReader br;
	private BufferedReader brConsole;
	private PrintStream ps;
	private InetAddress ip;

	public ThreadTalk(Socket s) {
		this.s = s;
	}

	public void run() {
		try {
			br = new BufferedReader(new InputStreamReader(s
					.getInputStream()));// 从客户端读取数据
			brConsole = new BufferedReader(
					new InputStreamReader(System.in)); // 从服务端读取数据
			ps = new PrintStream(s.getOutputStream()); // 向客户端输入数据
			//获得客户端ip地址
			ip = s.getInetAddress();
			ps.println("服务端传话:欢迎访问聊天服务器!");
			TalkThread tat = new TalkThread(brConsole, ps);
			tat.start(); // 这里用到多线程 实现双方互相对话
			String temp = "";
			while ((temp = br.readLine()) != null) {
				if (temp.equalsIgnoreCase("quit")) {
					System.out.println("与第" + ip+ "断开连接!");
					ps.println("断开连接,欢迎下次访问!");
					break;
				}
				System.out.println( ip+"说:" + temp);
			}
		} catch (IOException e) {
			if("Connection reset".equals(e.getMessage())){
				System.out.println("客户端异常退出!");
			}
		}finally {
			try {
				br.close();
				System.out.println(ip+"已断开链接!");
				s.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

class TalkThread extends Thread {
	private BufferedReader brConsole;
	private PrintStream ps;

	public TalkThread( BufferedReader brConsole,PrintStream ps) {
		super();
		this.brConsole = brConsole;
		this.ps = ps;
	}

	public void run() {
		String temp = "";
		try {
			while ((temp = brConsole.readLine())!= null) {
				ps.println(temp);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				brConsole.close();
				ps.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

 

 

 

客户端:

/**
 * @author $KangMiao$
 * 客户端
 * 与TCPTalkServer02.java一起用
 * 建立TCP双向通信客户端
 * 问题:①当客服端输入quit时 断开连接 但弹出异常,如下:
 * (已解决) 
 * java.net.SocketException: socket closed
	at java.net.SocketInputStream.socketRead0(Native Method)
	at java.net.SocketInputStream.read(Unknown Source)
	at sun.nio.cs.StreamDecoder$CharsetSD.readBytes(Unknown Source)
	at sun.nio.cs.StreamDecoder$CharsetSD.implRead(Unknown Source)
	at sun.nio.cs.StreamDecoder.read(Unknown Source)
	at java.io.InputStreamReader.read(Unknown Source)
	at java.io.BufferedReader.fill(Unknown Source)
	at java.io.BufferedReader.readLine(Unknown Source)
	at java.io.BufferedReader.readLine(Unknown Source)
	at com.wepull.task.zuoye11.TalkThred3.run(TcpClient.java:76)
 */

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
import java.net.UnknownHostException;

public class TCPTalkClient02 {
	private Socket s;
	private BufferedReader consBr; //控制台输入流
	private PrintStream ps;    //网络输出流
	private BufferedReader br;
	 
	public void conn(){
		 try {
			s = new Socket("localhost",8888);
			br = new BufferedReader(new InputStreamReader(s.getInputStream()));
			ps = new PrintStream(s.getOutputStream()); //写给服务端
			consBr = new BufferedReader(new InputStreamReader
					(System.in));       //从控制台读取数据
			TalkThred4 tt = new TalkThred4(consBr,ps);
			tt.start();
			String temp1 = "";
			while ((temp1 = br.readLine())!= null) {
				if (temp1.equalsIgnoreCase("quit")) {
					System.out.println("服务端与你断开连接!");
					break;
				}
				System.out.println("服务端传话:" +temp1);
			}
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			try {
				br.close();
				ps.close();
				s.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	public static void main(String[] args) {
		TCPTalkClient02 tc = new TCPTalkClient02();
		System.out.println("客户端连接中·········");
		tc.conn();
	}
}

class TalkThred4 extends Thread {
	private BufferedReader consBr;
	private PrintStream ps;

	public TalkThred4( BufferedReader consBr,PrintStream ps) {
		super();
		this.consBr = consBr;
		this.ps = ps;
	}

	public void run() {
		String temp = null;
		try {
			while((temp = consBr.readLine())!=null){
				ps.println(temp);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				consBr.close();
				ps.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值