【优化】IO流应用之网络传输
来源:互联网 发布:淘宝卖家怎么申请直播 编辑:程序博客网 时间:2024/06/06 09:13
javase已经看到网络编程了,快结束啦!掌声鼓励下。。。呵呵
经过一个月的自学,基本把java基础语法掌握的差不多了。我发现学的越多,就越喜欢java代码的简洁,清晰,很享受写代码的过程!加油吧,骚年!接下来就是通过小项目练手了!
废话不多说,下面是昨天写的代码,通过这个例子,我发现优化代码真的很重要!!!!
需求是这样子的,
客户端通过键盘录入用户名
服务端对这个用户名进行校验
如果该用户存在 在服务端显示xxx已登录
并在客户端显示xxx 欢迎光临
如果该用户不存在,在服务端显示xxx,尝试登陆
并在客户端显示xxx,该用户不存在
最多就登陆三次。
环境,控制台。
下面是我的代码。
用户数据存放在data.txt中
/* *本程序为方便调试,将客户端和服务端放在同一个.java文件中, *另外将ip地址设置为127.0.0.1,仅限本机登陆,如果连有局域网,可以 *进行局域网登陆测试,本人亲测通过。(需先获取对方ip)*/import java.net.*;import java.io.*;import java.util.*;//客户端class Client{//为保持代码简洁,这里抛出IO异常public static void main(String[] args)throws IOException{//建立socket服务Socket s=new Socket(InetAddress.getByName("127.0.0.1"),10006);BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));//键盘录入BufferedWriter bufw=new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));BufferedReader bufIn=new BufferedReader(new InputStreamReader(s.getInputStream()));String line=null;for(int i=0;i<3;i++){line=bufr.readLine();if(line==null)break;//将登录名发给服务端bufw.write(line);bufw.newLine();bufw.flush();//接收服务端反馈String dataRe=bufIn.readLine();System.out.println(dataRe);if(dataRe.contains("欢迎"))break;}s.close();}}//服务端class Server{public static void main(String[] args)throws IOException{//开启ServerSocket服务,监听一个端口ServerSocket ss=new ServerSocket(10006);while(true){Socket s=ss.accept();//多线程处理并发登陆new Thread(new LoginThread(s)).start();}}}class LoginThread implements Runnable{private Socket socket;private ArrayList<String> arr;LoginThread(Socket socket){this.socket=socket;}public void run(){try{System.out.println(socket.getInetAddress().getHostName()+"...connected");File file=new File("data.txt");//动态访问数据库,并遍历用户名,存入集合BufferedReader buda=new BufferedReader(new FileReader(file));String temp=null;arr=new ArrayList<String>();while((temp=buda.readLine())!=null){arr.add(temp);}//通过缓冲类包装getInputStream()和getOutputStream()方法BufferedReader bufr=new BufferedReader(new InputStreamReader(socket.getInputStream()));BufferedWriter bufw=new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));String line=null;//这里要求循环获取信息并反馈for(int i=0;i<3;i++){line=bufr.readLine();//获取客户端发来的信息if(line==null)break;//遍历集合Iterator<String> it=arr.iterator();int count=0;while(it.hasNext()){//检索到该用户名if(it.next().equals(line)){System.out.println(line+"已登录");//反馈信息bufw.write("尊敬的"+line+",欢迎光临");bufw.newLine();bufw.flush();break;}elsecount++;}if(count==arr.size()){System.out.println(line+"尝试登陆");bufw.write(line+"用户不存在");bufw.newLine();bufw.flush();}}socket.close();//超过三次,自动断开连接}catch(IOException e){throw new RuntimeException();}}}
以上代码通过不够优化,特别是将文件中的数据存到集合中,每开启一个线程都会执行一次,效率很低,而且是通过计数器来判断返回信息的,比较低效。
下面将代码稍微优化一下。
import java.io.*;import java.net.*;//客户端class NClient{public static void main(String[] args)throws IOException{//建立服务Socket s=new Socket(InetAddress.getByName("127.0.0.1"),10006);BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));//键盘录入BufferedWriter bufw=new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));BufferedReader bufIn=new BufferedReader(new InputStreamReader(s.getInputStream()));String line=null;String temp=null;for(int i=0;i<3;i++){//读取键盘录入,写入流中,注意,因为有缓冲,必须换行并刷新line=bufr.readLine();if(line==null)break;//如果录入为空,则退出循环bufw.write(line);bufw.newLine();bufw.flush();//接收服务端反馈temp=bufIn.readLine();System.out.println(temp);if(temp.contains("欢迎"))//登陆成功就退出循环break;}s.close();}}//服务端class NServer{public static void main(String[] args)throws IOException{ServerSocket ss=new ServerSocket(10006);while(true){Socket s=ss.accept();new Thread(new LoginThread(s)).start();}}}class LoginThread implements Runnable{private Socket s;LoginThread(Socket s){this.s=s;}public void run(){System.out.println(s.getInetAddress().getHostAddress()+"....connected");try{File file=new File("data.txt");BufferedReader bufr=new BufferedReader(new InputStreamReader(s.getInputStream()));BufferedWriter bufw=new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));boolean flag=false;String line=null;for(int i=0;i<3;i++){line=bufr.readLine(); if(line==null) break;BufferedReader buf=new BufferedReader(new FileReader(file));String temp=null;while((temp=buf.readLine())!=null)if(line.equals(temp)){flag=true;break;}if(flag){System.out.println(line+"已登录");bufw.write("尊敬的"+line+",欢迎光临");bufw.newLine();bufw.flush();}else{System.out.println(line+"尝试登陆");bufw.write(line+",该用户名不存在");bufw.newLine();bufw.flush();}}s.close();}catch(IOException e){//throw new RuntimeException();e.printStackTrace();}}}
优化后的代码通过判断标记flag的boolean值向客户端返回信息,很高效。
运行结果如下(同时打开两个控制台):
提示:需要先打开服务端!
这里注意一个细节,客户端和服务端都有这样一行代码:
if(line==null) break;
这是因为如果客户端第一次登陆已经登陆成功的话,就不必要继续登陆了,这时按ctrl+c退出时,服务端并不结束,且其readLine方法会读到null值,所以
我们在客户端加上这句判断。
思考:优化后的代码其实还可以继续优化,例如我们的BufferedWriter类每次write之后都需要换行并刷新缓冲区,
很麻烦,可以用PrinterWriter类,自动刷新。
- 【优化】IO流应用之网络传输
- 【JAVA开发之IO流1-4】IO流之数据流与网络传输基础
- 网络传输之网络协议
- TCP应用之对象流的传输
- Data Guard日志传输优化------网络传输优化实践
- SQLSERVER之(IO优化)
- 海量小文件网络传输copy优化
- 网络传输之序列化
- cocos2dx网络传输之CURL
- 网络编程之UDP传输
- 移动应用网络优化
- java基础之IO流的应用
- 黑马程序员-java之IO流应用
- 运维之基础网络篇-----5.传输层 、 应用层
- 五大感觉与网络传输应用
- 黑马程序员-java网络编程以及IO流的应用
- KVM 性能优化之磁盘IO优化
- 网站优化之服务器IIS压缩传输
- CLOB、BLOB , CLOB与BLOB的区别
- 织梦(dedecms)仿站教程第二十二讲——列表页制作(一)
- 2013工资新规定,未来的八种人将会被淘汰!
- win8_x86操作系统
- 织梦(dedecms)仿站教程第二十三讲——列表页制作(二)
- 【优化】IO流应用之网络传输
- 天勤OJ 题目1141: 大整数排序
- Wine下完美安装QQ 2010:
- JavaScript基础
- php 获取扩展名
- ASCII码文件和二进制码文件
- Java栈与堆
- weblogic与apache的整合与调优 --架构师第八天
- jQuery网格插件 ParamQuery