package H_Socket.C_Tcp; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; /** * 聊天室,一个客户端发送消息其他的客户端也可以接收到消息 */ //创建一个消息接收线程 class ChatReceive extends Thread{ BufferedReader bufferedReader; Socket socket; public ChatReceive(Socket socket){ this.socket = socket; } @Override public void run() { try { bufferedReader = new BufferedReader(new InputStreamReader(this.socket.getInputStream())); while (true){ synchronized ("a"){ //把从客户端接收到的信息给缓冲区 ChatServer.buf = bufferedReader.readLine(); //唤醒发送信息的线程对象 "a".notifyAll(); } } }catch (Exception e){ e.printStackTrace(); }finally { try { if (bufferedReader != null){ bufferedReader.close(); } if (socket != null){ socket.close(); } }catch (Exception e){ e.printStackTrace(); } } } } //创建一个消息发送线程 class ChatSend extends Thread{ PrintWriter printWriter; Socket socket; public ChatSend(Socket socket){ this.socket = socket; } @Override public void run() { try { while (true){ synchronized ("a"){ //让发送消息的线程处于等待状态 "a".wait(); //把接缓冲区的信息发送给其他的客户端 printWriter.println(ChatServer.buf); printWriter.flush(); } } }catch (Exception e){ e.printStackTrace(); }finally { try { if (socket != null){ socket.close(); } }catch (Exception e){ e.printStackTrace(); } } } } public class ChatServer { //定义公共区域 public static String buf; public static void main(String[] args) { ServerSocket serverSocket = null; try { System.out.println("监听83端口"); serverSocket = new ServerSocket(83); while(true){ Socket socket = serverSocket.accept(); System.out.println("连接到" + socket.getInetAddress()); new ChatSend(socket).start(); new ChatReceive(socket).start(); } }catch (Exception e){ e.printStackTrace(); }finally { try { if (serverSocket != null){ serverSocket.close(); } }catch (Exception e){ e.printStackTrace(); } } } }
package H_Socket.C_Tcp; import java.io.*; import java.net.ServerSocket; import java.net.Socket; import java.util.Scanner; /** * 在一个程序里既是客户端也可以是服务端,根据你输入的不同而不同 */ //发送线程 class Send extends Thread{ private Socket socket; private Scanner scanner; public Send(Socket socket){ this.socket = socket; } PrintWriter printWriter = null; @Override public void run() { try { printWriter = new PrintWriter(this.socket.getOutputStream()); scanner = new Scanner(System.in); while (true){ String message = scanner.nextLine(); printWriter.println(message); printWriter.flush(); } }catch (Exception e){ e.printStackTrace(); }finally { try { if (scanner != null){ scanner.close(); } if (printWriter != null){ printWriter.close(); } }catch (Exception e){ printWriter.println(); } } } } //接收线程 class Receive extends Thread{ private Socket socket; public Receive(Socket socket){ this.socket = socket; } BufferedReader bufferedReader = null; @Override public void run() { try { bufferedReader = new BufferedReader(new InputStreamReader(this.socket.getInputStream())); while (true){ String string = bufferedReader.readLine(); System.out.println("他说:" + string); } }catch (Exception e){ e.printStackTrace(); }finally { try { if (bufferedReader != null){ bufferedReader.close(); } if (socket != null){ socket.close(); } }catch (Exception e){ e.printStackTrace(); } } } } public class GoodTcp { public static void main(String[] args) throws Exception { Socket socket = null; ServerSocket serverSocket = null; Scanner scanner = null; try { scanner = new Scanner(System.in); System.out.println("请输入:server,<port> 或者:<ip>,<port>"); String s = scanner.nextLine(); String[] arrays = s.split(","); if ("server".equals(arrays[0])){ //启动服务端 System.out.println("TCP服务端监听" + arrays[1] + "端口,等待连接"); serverSocket = new ServerSocket(Integer.parseInt(arrays[1])); socket = serverSocket.accept(); System.out.println("连接成功"); }else { //启动客户端 socket = new Socket(arrays[0],Integer.parseInt(arrays[1])); System.out.println("连接成功"); } //启动发送线程 new Send(socket).start(); //启动接收线程 new Receive(socket).start(); }catch (Exception e){ e.printStackTrace(); }finally { try { if (serverSocket != null){ serverSocket.close(); } }catch (Exception e){ e.printStackTrace(); } } } }
显示连接成功,但是不能进行相互之间的通信
老师,我在看API文档的时候看到 创建由此类对象表示的类的新实例
我想问下:对象和实例有啥区别,能不能给我举个例子
老师好,我想问这个方法,是否是先返回父节点,再返回子节点?
如哺乳动物这个分支,是返回 [哺乳动物,猫,牛,人 ] 的顺序?
而不是[ 猫,牛,人,哺乳动物] 的顺序?
如果list不在方法内,
List<E> list = new ArrayList<>(); public List<E> getGrandChildren(E item){ }
即每次递归到下一层时,不new一个新的arraylist, 那么这个时候,是否是按照先子节点,最后父节点的顺序添加进去?
老师,在使用数据输入流时读取时如果不知道对方发是数据是什么类型,应该怎么读取来获得发送时数据的基本数据类型
laol老师,为什么判断数组是否为空以及判断数组要用while呀?判断一次不就行了,还要循环判断吗?
还有那个notify()的主要作用是防止两个synchronized块代码都进入阻塞状态吗?
老师,有2个问题:
1.数据流是处理流,里面可以之间放节点流,可以不用先在数据流里放缓冲流,再在缓冲流里放节点流吗?
2.加多一个缓冲流和不加好像都能读写数据,有上面区别呢?
/** * 发送信息的线程 */ class Send extends Thread{ private Socket socket; public Send(Socket socket){ this.socket = socket; } /** * 发送信息的方法 */ private void sendMsg(){ Scanner scanner = null; PrintWriter pw = null; try{ // 创建Scanner对象,通过键盘输入获取要发送的信息 scanner = new Scanner(System.in); // 创建字符输出流对象 用于向socket发送信息 pw = new PrintWriter(this.socket.getOutputStream()); while (true) { // 获取键盘输入的内容 String msg = scanner.nextLine(); // 将键盘输入的内容发送出去 pw.println(msg); // 刷新 pw.flush(); if("exit".equals(msg)){ break; } } }catch (Exception e){ e.printStackTrace(); }finally { try { if(scanner != null){ scanner.close(); } if(pw != null){ pw.close(); } if (this.socket != null){ socket.close(); } }catch (Exception e){ e.printStackTrace(); } } } @Override public void run() { this.sendMsg(); } } /** * 接受信息的线程 */ class Receive extends Thread{ private Socket socket; public Receive(Socket socket){ this.socket = socket; } /** * 接受信息的方法 */ private void receiveMsg(){ BufferedReader br = null; try { // 创建用于接受对方发送信息的流对象 br = new BufferedReader(new InputStreamReader(this.socket.getInputStream())); while (true){ String msg = br.readLine(); System.out.println("他说:"+msg); if ("exit".equals(msg)){ break; } } }catch (Exception e){ e.printStackTrace(); }finally { try { if(br != null){ br.close(); } if(this.socket != null){ this.socket.close(); } }catch (Exception e){ e.printStackTrace(); } } } @Override public void run() { this.receiveMsg(); } }
老师我添加了一个判断是否结束聊天的判断,但是这样写运行时只能是发送信息的一方关闭,接收的不会关闭
而且发送放会先报个异常再关闭
报错行数是以下两个
pw = new PrintWriter(socket.getOutputStream());
老师PrintWriter可以直接将字节流转为字符流,不需要借助转换流吗?
finally { try { // 关闭流和Socket对象 if (br != null){ br.close(); } if(socket != null){ socket.close(); } }catch (Exception e){ e.printStackTrace(); } }
关闭时可以这样写吗?还是br和socket要分开try-catch
当我打开第二个goodTCP出现报错现象
老师,这个class对象可以用字符串作为对象锁吗?
感觉使用字符串作为对象锁和class对象锁都是属于不同的对象操作不同的线程,而this是属于同一个对象操作不同的多线程,可以这样理解吗?
pw.println(str); pw.flush();
PrintWriter字符输出流不是自动flush清空缓存吗,为什么不添加发送不了信息?
还有为什么使用pw.print不能发生信息,pw.println才可以
class Makeup extends Thread{ private int flag; private String girlName; static private Lipstick2 lipstick = new Lipstick2(); static private Mirror mirror = new Mirror();
class ShengChan extends Thread{ private SyncStack ss; public ShengChan(SyncStack ss) { this.ss = ss; }
老师这两个实例化某个对象变量有什么区别,应该在什么情况下使用?
这个电话本项目没有储存功能吗,我打开添加新记录,关闭程序后,之前保存的记录都没有了。
非常抱歉给您带来不好的体验!为了更深入的了解您的学习情况以及遇到的问题,您可以直接拨打投诉热线:
我们将在第一时间处理好您的问题!
关于
课程分类
百战程序员微信公众号
百战程序员微信小程序
©2014-2025百战汇智(北京)科技有限公司 All Rights Reserved 北京亦庄经济开发区科创十四街 赛蒂国际工业园网站维护:百战汇智(北京)科技有限公司 京公网安备 11011402011233号 京ICP备18060230号-3 营业执照 经营许可证:京B2-20212637