(15)Java网络编程-应用练习篇

来源:互联网 发布:程序员面试自我介绍 编辑:程序博客网 时间:2024/06/11 02:21
---------------------- ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------

     Java网络编程-应用练习篇

这一篇主要是一些常见应用分析和练习。

练习一:

/*通过tcp协议,客户端上传图片给服务端,服务端将图片数据发送到指定目的(硬盘)并给客户端返回上传成功。分析步骤:客户端1,创建socket服务指定客户端点2,读取客户端指定图片数据3,通过socket输出流将图片数据发送服务端并定义结束标记4,通过流对象接收服务端返回的上传信息5,关闭流资源服务端1,创建ServerSocket服务端并指定端口号2,读取客户端发送来的图片数据并存储缓冲区3,将缓冲区里的数据写入到指定目的地4,返回客户端上传信息5,关闭流资源。*/import java.net.*;import java.io.*;class  PicClient{//客户端public static void main(String[] args) throws Exception{Socket s = new Socket("192.168.0.2",10006);//读取指定的图片FileInputStream fis = new FileInputStream(new File("c:\\背景.jpg"));//Socket服务的输出流将数据发送OutputStream out = s.getOutputStream();//定义一个缓冲区byte[] buy = new byte[1024];int len = 0;while ((len= fis.read(buy))!=-1){out.write(buy,0,len);}//定义结束标记,告诉服务端数据传送完毕s.shutdownOutput();//通过socket读取流,读取服务端返回的信息InputStream is = s.getInputStream();byte[] b = new byte[1024];int leng = is.read(b);System.out.println(new String(b,0,leng));fis.close();s.close();}}class  PicServer//服务端{public static void main(String[] args) throws Exception{ServerSocket ss = new ServerSocket(10006);Socket s = ss.accept();//获取客户端iPhone地址String ip = s.getInetAddress().getHostAddress();System.out.println(ip);InputStream is = s.getInputStream();FileOutputStream fos = new FileOutputStream("c:\\复制图片.jpg");byte[] buy = new byte[1024];int len = 0;while ((len=is.read(buy))!=-1){fos.write(buy,0,len);}OutputStream os = s.getOutputStream();os.write("上传成功".getBytes());fos.close();s.close();ss.close();}}


练习二:

TCP客户端并发上传图片

思考问题:

1, 通过上面的练习了解到,这是一个单线程的服务,其局限性是当a客户连接服务端后正常秩序流程,若b客户想要连接只能等待,因为服务端必须把a客户端的请求处理完才能执行b客户端的请求,所以暂时获取不到b客户端对象。

2, 若客户端发送过来的文件不是图片文件或者文件过大怎办?

解决:

1, 为了让多个客户可以同时并发访问服务端,服务端最好的方法就是把每个客户封装到单独的一个线程中,这样就可以同时处理多个客户的请求。

2, 创建文件对象,判断传送进来的文件是否符合指定规则,若不符合返回信息。

怎么定义线程呢?

只要明确了每个客户端在服务端执行的代码,将代码存入run方法即可

示例:

/*客户端并发请求的练习*/import java.net.*;import java.io.*;class  PicClientDemo{public static void main(String[] args) throws Exception{//判断传入的值if(args.length!=1){System.out.println("请输入一个标准图片");return;}//创建文件对象File file=new File(args[0]);  //判断文件是否存在if (!(file.exists()&&file.isFile())){System.out.println("传入的路径错误或文件不存在或不是文件");return;}//判断文件是否是指定格式if (!(file.getName().endsWith(".jpg"))){System.out.println("传入的文件格式不对");return;}//判断文件大小if (file.length()>1024*1024*8){System.out.println("传入的文件大于8M");return;}Socket s = new Socket("192.168.0.2",10006);//读取指定的图片FileInputStream fis = new FileInputStream(file);//Socket服务的输出流将数据发送OutputStream out = s.getOutputStream();//定义一个缓冲区byte[] buy = new byte[1024];int len = 0;while ((len= fis.read(buy))!=-1){out.write(buy,0,len);}//定义结束标记,告诉服务端数据传送完毕s.shutdownOutput();//通过socket读取流,读取服务端返回的信息InputStream is = s.getInputStream();byte[] b = new byte[1024];int leng = is.read(b);System.out.println(new String(b,0,leng));fis.close();s.close();}}//利用多线程实现并发上传数据class PicThread implements Runnable{private Socket s;PicThread(Socket s){this.s = s;}public void run(){try{//获取客户端iP地址String ip = s.getInetAddress().getHostAddress();System.out.println(ip);InputStream is = s.getInputStream();int count = 1;//文件保存路径File dir = new File("c:\\");File file = new File(dir,"复制图片.jpg");//判断文件是否存在while (file.exists()){file = new File(dir,"复制图片("+(count++)+").jpg");}//将上传的数据存进指定输出流FileOutputStream fos = new FileOutputStream(file);byte[] buy = new byte[1024];int len = 0;while ((len=is.read(buy))!=-1){fos.write(buy,0,len);}//返回上传信息给客户端OutputStream os = s.getOutputStream();os.write("上传成功".getBytes());fos.close();s.close();}catch (Exception e){throw new RuntimeException("数据上传失败");}}}class  PicServerDemo{public static void main(String[] args) throws Exception{//创建服务端Socket服务,监听端口ServerSocket ss = new ServerSocket(10006);//主线程循环执行或将上传的客户端数据while (true){//获取客户端对象Socket s = ss.accept();//创建并开启客户端线程new Thread(new PicThread(s)).start();}}}

练习三:

/*练习:客户端并发登陆客户端通过键盘录入用户名,服务端对这个用户进行校验。若该用户存在,在服务端显示XXX,已登录;并在客户端显示XXX,欢迎光临。若用户不存在,在服务端显示XXX,尝试登陆;并在客户端显示XXX,该用户不存在,且最多登陆三次*/import java.net.*;import java.io.*;//客户端class LoginClinet{public static void main(String[] args) throws Exception{//创建服务Socket s = new Socket("192.168.0.2",10007);//键盘录入BufferedReader bufs = new BufferedReader(new InputStreamReader(System.in));//使用Socket的输出流将数据写入PrintWriter ps = new PrintWriter(s.getOutputStream(),true);//接收服务器返回的信息BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));String line = null;//设置登陆次数for (int x = 1;x<=3 ;x++ ){line = bufs.readLine();//获取键盘信息if(line==null)break;ps.println(line);//将数据发送服务端String info = br.readLine();//获取服务端返回信息System.out.println(info);if (info.contains("欢迎"))break;}bufs.close();s.close();}}//利用多线程实现并发登陆class LoginThread implements Runnable{private Socket s;LoginThread(Socket s){this.s = s;}public void run(){try{for (int x = 1;x<=3 ;x++ )//在服务端限制登陆次数{//获取客户端ip地址String ip = s.getInetAddress().getHostAddress();System.out.println("客户端iP:"+ip);//通过socket服务读取流获取客户端发送的信息BufferedReader bufr = new BufferedReader(new InputStreamReader(s.getInputStream()));//关联数据库,查询是否有该客户端信息,这时自定义数据库一个文本文件内存储的是用户名BufferedReader in = new BufferedReader(new FileReader("c:\\users.txt"));String line = bufr.readLine();//获取信息if (line==null){break;//当接收的是null时退出}String data = null;boolean flag = false;while ((data= in.readLine())!=null){if (line.equals(data)){flag = true;break;}}//通过socket服务输出流,给发送客户端登陆信息PrintWriter ps = new PrintWriter(s.getOutputStream(),true);if (flag){ps.println(line+",欢迎光临");System.out.println(line+",已登录");break;}else{ps.println(line+"该用户不存在,请重新登陆");System.out.println(line+"尝试登录");}}s.close();}catch (Exception e){throw new RuntimeException("用户登陆失败");}}}//服务端class  LoginServer{public static void main(String[] args) throws Exception{ServerSocket ss = new ServerSocket(10007);//创建服务端并监听端口;while (true){Socket s = ss.accept();//获取客户端对象new Thread(new LoginThread(s)).start();//创建并开启多线程}}}模拟数据库:


打印结果:



练习三(关于浏览器客户端显示):

/*浏览器客户端-自定义服务端浏览器是一个标准的客户端,它可以对服务端传输过来的数据进行解析,把符合应用层协议的消息部分解析后,将头信息拆包,传送到应用层,只保留正确的正文主题部分县市在客户端上。因为java编译使用的是传输层和网际层处理数据,所以接收全部消息并包含头消息。浏览器处于应用层,编译时将头消息编译,只留下主题信息示例:演示客户端和服务端客户端:浏览器服务端:自定义*/import java.net.*;import java.io.*;class  ServerDemo{public static void main(String[] args)throws Exception {ServerSocket ss = new ServerSocket(11000);Socket s = ss.accept();PrintWriter pw = new PrintWriter(s.getOutputStream(),true);pw.println("<font color='red' size='7'>浏览器您好,我是服务端发送给您的消息。</font>");s.close();ss.close();}}在浏览器输入ip地址加端口号即可显示


URL-URLConnection

概述:

类 URL 代表一个统一资源定位符,它是指向互联网“资源”的指针。资源可以是简单的文件或目录,也可以是对更为复杂的对象的引用,例如对数据库或搜索引擎的查询。

URI:范围大,条形码等也包含咋此范围内

URL:范围小即域名

常用构造方法:

//根据指定 protocolhostport号和 file 创建 URL对象。

URL(String protocol,String host,int port,String file); 

常用方法:

 String

getFile() 
          获取此 URL 的文件名。

 String

getHost() 
          获取此 URL 的主机名(如果适用)。

 String

getPath() 
          获取此 URL 的路径部分。

 int

getPort() 
          获取此 URL 的端口号。

 String

getProtocol() 
          获取此 URL 的协议名称。

 String

getQuery() 
          获取此 URL 的查询部分。


URLConnection 

抽象类 URLConnection 是所有类的超类,它代表应用程序和 URL 之间的通信链接。此类的实例可用于读取和写入此 URL 引用的资源

openConnection();//对影响到远程资源连接的参数进行操作。

 示例:

/*需求:自定义图形化界面浏览器即客户端分析步骤:1,自定义浏览器构造图形化界面2,注册事件监听机制3,通过创建URL对象接收服务端发送来的数据*/import java.net.*;import java.io.*;import java.awt.*;import java.awt.event.*;class  MyIEDemo{//定义所需组件引用private Frame f;private Button but;private TextArea ta;private TextField tf;//构造函数MyIEDemo(){info();}private void info(){//组件实例化f = new Frame("我的网页窗口");ta = new TextArea(60,50);tf = new TextField(40);but = new Button("搜索");//对窗口进行设置f.setBounds(300,200,400,370);f.setLayout(new FlowLayout());//添加组件f.add(tf);f.add(but);f.add(ta);//事件监听myEvent();//显示窗口f.setVisible(true);}private void myEvent(){//对窗口注册关闭监听f.addWindowListener(new WindowAdapter(){public void windowClosing(WindowEvent e){System.exit(0);}});//对按钮注册活动监听but.addActionListener(new ActionListener(){public void actionPerformed(ActionEvent e){showFile();//若点击按钮,就会将收索的内容显示文本区}});//对文本框注册键盘监听tf.addKeyListener(new KeyAdapter(){public void keyPressed(KeyEvent e){if (e.getKeyCode()==KeyEvent.VK_ENTER)showFile();//若敲回车就会就会将收索的内容显示文本区}});}private void showFile(){//清空文本区ta.setText("");//获取键盘录入的路径String path = tf.getText();try{/*重点分析:这里就不用写socket,因为它已经封装进了URL里面,并且还封装了HTTP等协议,现在就不再传输层而是在应用层。*///将地址封装成对象URL url = new URL(path);//链接网页服务器,对远程资源连接的参数进行操作。URLConnection conn = url.openConnection();//读取流,用于读取服务器返回数据 InputStream in = conn.getInputStream();byte[] buy = new byte[1024]; int len=in.read(buy);                    //将数据显示在文本区中                    ta.append(new String(buy,0,len)); }catch (Exception e){throw new RuntimeException("网络"+path+"链接失败");}}public static void main(String[] args) throws Exception{new MyIEDemo();}}

网络编程-小知识点

1Socket类中空参数的构造函数

通过connect(SocketAddress endpoint)方法来连接服务器,

因为SocketAddress是一个抽象类,他的子类InetSocketAddress实现了IP套接字地址(ip+端口号)。

2,在ServerSocket构造函数:ServerSocket(int port,int backlog)

Backlog标示队列的最大长度即客户端连接服务器的个数。

1, DNS域名解析

当我们在浏览器输入如www.baidu.com主机名时浏览器是如何通过主机名获取该主机ip地址的呢?

解决:

这就需要将主机名翻译成IP地址,即域名解析:DNS

在进行访问的时候,会先在本地的hosts文件(c:\windows\system32\drivers\ect\host中找对应的映射。若有,则直接返回请求;若无,则到公网的映射列表即DNS中找对应的映射,找到后,将主机名对应的IP地址返回给本机,本机通过这个IP地址找到对应的服务器。

---------------------- ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------详细请查看:http://edu.csdn.net
0 0
原创粉丝点击