多线程和网络编程实践——LittleTom
来源:互联网 发布:php base64 中文乱码 编辑:程序博客网 时间:2024/06/16 08:02
这两天写了一个小应用,实现基本的聊天功能。该应用既是客户端也是服务器,不要求某一方先发起连接请求。但同一时间仅能两个ip互相传输数据。用上了最近学的多线程和网络编程相关知识。先贴上初稿,还有问题,以后有空再琢磨琢磨。
两个类:LittleTom.class, TalkThread.class
1. LittleTom.java
import java.io.*;import java.net.*;public class LittleTom { private Wait waitThread = null; private Connect connectThread = null; private ServerSocket waitSocket; private Socket socket; private BufferedReader br = null; private int waitPort = 10001; private int connectPort = 10002; private boolean isConnecting = false; public LittleTom() { br = new BufferedReader(new InputStreamReader(System.in)); waitThread = new Wait(); connectThread = new Connect(); waitThread.start(); connectThread.start(); } class Wait extends Thread { public void run(){ waitConnect(); } synchronized private void waitConnect() { try { waitSocket = new ServerSocket(waitPort); while(true) { if(!isConnecting) { Socket memberSocket = waitSocket.accept(); if(!isConnecting) { isConnecting = true; System.out.println(memberSocket.getInetAddress().getHostName() + " want to talk with you."); new TalkThread(LittleTom.this, memberSocket); } else { System.out.println("Wait::You can only speak with one preson at the same time."); continue; } } else { wait(); } } } catch(Exception e) { e.printStackTrace(); } finally { try { if(waitSocket != null){ waitSocket.close(); } if(socket != null) { socket.close(); } br.close(); } catch(Exception e) { e.printStackTrace(); } } } } class Connect extends Thread { public void run(){ tryToConnect(); } synchronized private void tryToConnect() { try{ while(true) { if(!isConnecting) { System.out.println("Please input the IP that you want to talk with: "); br = new BufferedReader(new InputStreamReader(System.in)); String input = br.readLine();// String IP = "109.123.102.117"; if(!isConnecting) { isConnecting = true; System.out.println("Try to connecting..."); socket = new Socket(input, connectPort); new TalkThread(LittleTom.this, socket); } else { System.out.println("Connect::You can only speak with one preson at the same time."); continue; } } else { wait(); } } } catch(Exception e) { System.out.println("connect fail."); e.printStackTrace(); } finally { try { if(waitSocket != null){ waitSocket.close(); } if(socket != null) { socket.close(); } br.close(); } catch(Exception e) { e.printStackTrace(); } } } } public void resetConnection() { isConnecting = false; synchronized(waitThread) { waitThread.notify(); } synchronized(connectThread) { connectThread.notify(); } } public BufferedReader getSystemBuffer() { return br; } public static void main(String[] args) { LittleTom lt = new LittleTom(); } }
2. TalkThread.java
import java.io.*;import java.net.*;public class TalkThread { private LittleTom littleTom; private Socket memberSocket; private String peer; private InputStream is; private OutputStream os; private Thread receiveThrd = null; private Thread sendThrd = null; public TalkThread(LittleTom lt, Socket socket){ try { this.littleTom = lt; this.memberSocket = socket; peer = memberSocket.getInetAddress().getHostName(); is = memberSocket.getInputStream(); os = memberSocket.getOutputStream(); receiveThrd = new Thread() { public void run(){ receive(); sendThrd.stop(); close(); littleTom.resetConnection(); } }; sendThrd = new Thread() { public void run(){ send(); receiveThrd.stop(); close(); littleTom.resetConnection(); } }; receiveThrd.start(); sendThrd.start(); } catch(Exception e) { e.printStackTrace(); } } private void receive() { byte[] b = new byte[1024]; String receiveMsg = null; try { do { int n = is.read(b); if(n<=0) { continue; } receiveMsg = new String(b, 0, n); System.out.println(peer + " say >>>> " + receiveMsg); } while(receiveMsg == null || !receiveMsg.equalsIgnoreCase("exit")); } catch(Exception e) { if(memberSocket.isClosed()){ System.out.println("receive::socket is closed."); } else { e.printStackTrace(); } } } private void send() {// byte[] b = new byte[1024]; String input = null; try { do { input = littleTom.getSystemBuffer().readLine(); if(input == null) { continue; } System.out.println("I say >>>> " + input); os.write(input.getBytes()); } while((input == null) || (!input.equalsIgnoreCase("exit"))); } catch(Exception e) { if(memberSocket.isClosed()){ System.out.println("send::socket is closed."); } else { e.printStackTrace(); } } } public void close() { try { is.close(); os.close(); memberSocket.close(); } catch(Exception e) { e.printStackTrace(); } }}
程序运行起来还有问题:
1. 被动接受连接的一方,第一次用户输入的数据不能发送出去。原因是数据被tryToConnect读到,并被认为是用户输入的IP地址,所以尝试去连接。连接失败,打印"Connect::You can only speak with one preson at the same time.", 再次进入循环的时候,由于isConnecting==true,直接进入等待。然后后面用户的输入就能发送出去了。但是怎么修复这个bug啊?
2. 连接只能进行一次。一方exit,然后再尝试去连就连不上了。但是程序并没有退出。求高手解答。
- 多线程和网络编程实践——LittleTom
- UNIX网络编程——Socket通信原理和实践
- 多线程和网络编程
- 网络编程和多线程
- 多线程和网络编程
- 网络编程——断点续传和多线程下载模式
- 网络编程——断点续传和多线程下载模式
- 网络编程——断点续传和多线程下载模式(转)
- 网络编程——断点续传和多线程下载模式
- windows多线程和网络编程
- linux网络编程之—多线程模型 .
- 多线程编程和网络编程入门
- 【Java】网络编程的简单应用,多线程下载最佳实践
- 网络编程——多线程技术实现网络聊天程序
- 黑马程序员——网络编程(二)------UDP、TCP和多线程
- 黑马程序员——Java学习总结:多线程和网络编程
- Java_基础—网络编程(TCP协议代码及其优化和服务器多线程优化)
- C#多线程编程实践
- 查看物理CPU个数与逻辑处理器的个数
- Jni中C++和Java的参数传递
- C#程序实现动态调用DLL的研究
- 存储过程的优缺点
- JS 将JSON对象转换为字符串
- 多线程和网络编程实践——LittleTom
- 2、C语言中变量的存储,生存周期,作用范围分类
- java将xml文件自动转换成java类
- 各种数据库分页查询语句
- python中如何调用shell 中OS.SYSTEM等方法
- UVa 111 - History Grading
- 有用的小代码
- MFC重复行删除工具(C/C++) 文本文件 结合BeyonCompare 找出不同的
- windbg 設置