黑马程序员——java之网络编程

------------android培训java培训、期待与您交流! ------------- 

1、软件之间通信条件:

a.找到对方IP
b.数据要发送到对方指定的应用程序上,为了表示这些程序,所以给这些网络应用程序都用数字进行标示。
   为了方便称呼这个数字,叫做端口,逻辑端口。
c.定义通信规则。既成为协议,通用为TCP/IP

 

2、本地回环地址:127.0.0.1(可以测试网卡用,ping

         IPV6(包含数字和字母)

     端口号的范围为0---65535之间,0----1023之间的端口数是用于一些知名的网络服务和应用  

     Web服务端口一般是80.

3、网络参考模型:

 

每一层都有自己的封装数据规则,以此区分数据包。一层层传递,层层封,层层拆。

WEB开发在应用层(URLFTPHTTP)混;

现在是在传输层(TCP)和网际(IP)层混;

4、Socket:

Socket就是为网络服务提供的一种机制。

通信的两端都有Socket

网络通信其实就是Socket间的通信。

数据在两个Socket间通过IO传输。

Socket是网络驱动层提供给应用程序编程的接口和一种机制 

可以吧Socket比喻成是一个港口码头。应用程序只要把货物放到港口码头上,就算完成了货物的运送。应用程序只需等待货物到达码头后,将货物取走 

Socket在应用程序中创建,通过一种绑定机制与驱动程序建立关系,告诉自己所对应的IPPort

 

5、InetAddress

主要的方法:

InetAddress:构造方法私有,不能直接创建对象。

InetAddressgetByName(String host):在给定主机名的情况下确定主机的ip地址。

InetAddressgetLocalHost():返回本地主机。

InetAddress[]getAllByName(String host)

ip.getHostAddress(), 

ip.getHostName()

InetAddress[] getAllByName(String host)   throws UnknownHostException

对应一个name对应多个主机的状态(例如百度),最好获取IP不取name

   网络通信其实就是Socket间的通

[java]  view plain copy print ?
  1. public class InetAddressDemo {  
  2.   
  3.     /** 
  4.      * @param args 
  5.      * @throws IOException  
  6.      */  
  7.     public static void main(String[] args) throws IOException {  
  8.         // TODO Auto-generated method stub  
  9.         InetAddress local = InetAddress.getLocalHost();  
  10.         System.out.println(local.toString());  
  11.         //virtor/192.168.12.101,还有getHostAddress();getHostName()两个方法  
  12.           
  13.         InetAddress[] baidu = InetAddress.getAllByName("www.baidu.com");//可见百度两个服务器,不过不知道真的假的  
  14.         for(InetAddress ip1 :baidu){  
  15.             System.out.println(ip1.toString());  
  16. //          打印结果:www.baidu.com/61.135.169.125  
  17. //                 www.baidu.com/61.135.169.105  
  18.         }  
  19.     }  
  20.   
  21.   }  


 


 

6、传输协议:

 

 在传输层常用的两个协议为UDPTCP 

UDP

将数据及源和目的封装成数据包中,不需要建立连接

每个数据报的大小在限制在64k

因无连接,是不可靠协议、容易丢包

不需要建立连接,速度快

相当于到邮局寄邮件,对方的地址、姓名要写上。但是接收人不一定及时接收。

qq聊天工具、飞信、凌波等

TCP

建立连接,形成传输数据的通道。

在连接中进行大数据量传输

通过三次握手完成连接,是可靠协议

必须建立连接,效率会稍低

  相当于打电话

 

7、UDP传输

DatagramSocket与DatagramPacket

建立发送端,接收端。

建立数据包。

调用Socket的发送接收方法。

关闭Socket

发送端与接收端是两个独立的运行程序。

 

Udp发送、接收代码示例

[java]  view plain copy print ?
  1. import java.net.*;  
  2. /* 
  3. 需求:通过udp传输方式,将一段文字数据发送出去。, 
  4. 定义一个udp发送端。 
  5. 思路: 
  6. 1,建立updsocket服务。 
  7. 2,提供数据,并将数据封装到数据包中。 
  8. 3,通过socket服务的发送功能,将数据包发出去。 
  9. 4,关闭资源。 
  10.   */  
  11. class  UDPSend{  
  12.     public static void main(String[] args) throws Exception {  
  13.         //1,创建udp服务。通过DatagramSocket对象。  
  14.         DatagramSocket ds = new DatagramSocket(8888);  
  15.   
  16.         //2,确定数据,并封装成数据包。DatagramPacket(byte[] buf, int length, InetAddress address, int port)   
  17.   
  18.         byte[] buf = "董方宇".getBytes();  
  19.         DatagramPacket dp =   
  20.             new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.254"),10000);  
  21.   
  22.         //3,通过socket服务,将已有的数据包发送出去。通过send方法。  
  23.         ds.send(dp);  
  24.   
  25.         //4,关闭资源。  
  26.         ds.close();  
  27.     }  
  28. }  
  29.   
  30. /* 
  31. 需求: 
  32. 定义一个应用程序,用于接收udp协议传输的数据并处理的。 
  33. 定义udp的接收端。 
  34. 思路: 
  35. 1,定义udpsocket服务。通常会监听一个端口。其实就是给这个接收网络应用程序定义数字标识。 
  36.     方便于明确哪些数据过来该应用程序可以处理。 
  37.  
  38. 2,定义一个数据包,因为要存储接收到的字节数据。 
  39. 因为数据包对象中有更多功能可以提取字节数据中的不同数据信息。 
  40. 3,通过socket服务的receive方法将收到的数据存入已定义好的数据包中。 
  41. 4,通过数据包对象的特有功能。将这些不同的数据取出。打印在控制台上。 
  42. 5,关闭资源。 
  43.  
  44. */  
  45. class  UDPRece{  
  46.     public static void main(String[] args) throws Exception{  
  47.         //1,创建udp socket,建立端点。这里必须定义监听的端口,其实就是给网络应用程序定义数字标识。   
  48.         DatagramSocket ds = new DatagramSocket(10000);  
  49.         while(true){  
  50.         //2,定义数据包。用于存储数据。  
  51.         byte[] buf = new byte[1024];  
  52.         DatagramPacket dp = new DatagramPacket(buf,buf.length);  
  53.   
  54.         //3,通过服务的receive方法将收到数据存入数据包中。  
  55.         ds.receive(dp);//阻塞式方法。没接到数据则一直等待  
  56.           
  57.         //4,通过数据包的方法获取其中的数据。  
  58.         String ip = dp.getAddress().getHostAddress();  
  59.   
  60.         String data = new String(dp.getData(),0,dp.getLength());  
  61.     
  62.         int port = dp.getPort();  
  63.   
  64.         System.out.println(ip+"::"+data+"::"+port);  
  65.   
  66.         }  
  67.         //5,关闭资源  
  68.         s.close();  
  69.     }  
  70. }  

UDP练习:聊天程序

[java]  view plain copy print ?
  1. /*一个发送端,一个接收端,实现聊天*/  
  2. import java.io.*;    
  3.     
  4. class  UdpSend2    
  5. {    
  6.     public static void main(String[] args) throws Exception    
  7.     {    
  8.         DatagramSocket dg = new DatagramSocket(18000);    
  9.         //读取键盘录入    
  10.         BufferedReader bufr =    
  11.             new BufferedReader(new InputStreamReader(System.in));    
  12.     
  13.         String line = null;    
  14.         //192.168.1.255是这个网段的广播地址,用它就能实现局域网群聊。    
  15.         InetAddress ip = InetAddress.getByName("192.168.1.255");    
  16.         DatagramPacket dp = null;     
  17.         while((line=bufr.readLine())!=null)    
  18.         {    
  19.             if("over".equals(line))    
  20.                 break;    
  21.             byte [] buf = ("sender:"+line).getBytes();    
  22.             dp = new DatagramPacket(buf,0,buf.length,ip,17000);    
  23.             dg.send(dp);    
  24.         }    
  25.         dg.close();    
  26.             
  27.     }    
  28. }    
  29.     
  30. class  UdpRece2    
  31. {    
  32.     public static void main(String[] args) throws Exception    
  33.     {    
  34.         DatagramSocket dg = new DatagramSocket(17000);    
  35.         byte[] buf = new byte[1024];    
  36.         DatagramPacket dp = new DatagramPacket(buf,buf.length);    
  37.         while(true)    
  38.         {    
  39.             dg.receive(dp);    
  40.             String ip = dp.getAddress().getHostAddress();    
  41.             String data = new String(dp.getData(),0,dp.getLength());    
  42.             System.out.println("("+ip+":"+dp.getPort()+")"+data);    
  43.             //System.out.println(new String(buf,0,dp.getLength()));    
  44.         }    
  45.         //dg.close();因为无限循环,这句读不到    
  46.             
  47.     
  48.     }    
  49. }    
  50. /*实现多线程,一个窗口就可以!   
  51. 编写一个聊天程序   
  52. 有接受数据的部分,和发数据的部分。   
  53. 这两部分需要同时执行。那就需要用到多线程技术。   
  54. 一个线程控制收,一个线程控制发。   
  55.    
  56. 因为收和发动作是不一致的,所以要定义两个run方法,   
  57. 而且run方法要封装到不同的类中。     
  58. */    
  59. /* 
  60. 编写一个聊天程序。 
  61. 有收数据的部分,和发数据的部分。 
  62. 这两部分需要同时执行。 
  63. 那就需要用到多线程技术。 
  64. 一个线程控制收,一个线程控制发。 
  65.  
  66. 因为收和发动作是不一致的,所以要定义两个run方法。 
  67. 而且这两个方法要封装到不同的类中。 
  68.  
  69. */  
  70. import java.io.BufferedReader;  
  71. import java.io.IOException;  
  72. import java.io.InputStreamReader;  
  73. import java.net.DatagramPacket;  
  74. import java.net.DatagramSocket;  
  75. import java.net.InetAddress;  
  76.   
  77. public class ChatDemo {  
  78.   
  79.     /** 
  80.      * @param args 
  81.      * @throws IOException  
  82.      */  
  83.     public static void main(String[] args) throws IOException {  
  84.         // TODO Auto-generated method stub  
  85.             //创建两个Udp的socket对象,一个接收端一个发送端  
  86.         DatagramSocket send = new DatagramSocket();  
  87.         DatagramSocket rece = new DatagramSocket(10086);  
  88.         //创建两个匿名的线程对象,传入实现Runnable接口覆盖run方法的两个匿名聊天对象,开启多线程。  
  89.         new Thread(new SendMes(send)).start();  
  90.         new Thread(new Rece(rece)).start();  
  91.     }  
  92.   
  93. }  
  94.   
  95. class SendMes implements Runnable{  
  96.     private DatagramSocket  send ;  
  97.     SendMes(DatagramSocket ds){  
  98.         this.send = ds;  
  99.     }  
  100.       
  101.     public void run(){  
  102.         //把键盘输入流封装成对象  
  103.         BufferedReader br =   
  104.                 new BufferedReader(new InputStreamReader(System.in));  
  105.           
  106.           
  107.         String line = null;  
  108.         try {  
  109.             while((line = br.readLine())!= null){  
  110.                   
  111.                 byte[] buf = line.getBytes();  
  112.                 InetAddress id = InetAddress.getByName("127.0.0.1");  
  113.                 DatagramPacket dp =   
  114.                         new DatagramPacket(buf, 0,buf.length,id , 10086);//建一个数据包用来封装键盘录入的数据  
  115.                 send.send(dp);  //通过send方法把数据包发送出去  
  116.   
  117.                 if(line.equals("886"))  {   //必须在最后判断,不然下边都关socket了,怎么把886发给接收端!  
  118.                    System.out.println("不聊了");  
  119.                     send.close();  
  120.                     break;    
  121.                 }  
  122.             }  
  123.               
  124.             send.close();  
  125.         } catch (IOException e) {  
  126.             // TODO Auto-generated catch block  
  127.             e.printStackTrace();  
  128.         }  
  129.         //send.close();  
  130.     }  
  131. }  
  132.   
  133. class Rece implements Runnable{  
  134.     private DatagramSocket rese;  
  135.     public Rece(DatagramSocket ds){//接收端的Udp要侦听端口,所以传入的DatagramSocket对象要指定端口  
  136.         this.rese = ds;  
  137.     }  
  138.     public void run(){  
  139.           
  140.         while(true){  
  141.               
  142.             byte [] buf = new byte[1024];  
  143.             DatagramPacket dp = new DatagramPacket(buf,buf.length);//建一个数据包,用来接收发送端发送的数据  
  144.             try {  
  145.                 rese.receive(dp);//接收数据,封装到dp包中!  
  146.                   
  147.                 String ip = dp.getAddress().toString();//获取ip  
  148.                 String data = new String(dp.getData(),0,dp.getLength());//获取数据并封装成String  
  149.                       
  150.                 if(data.equals("886"))//同样放在最后  
  151.                 {  
  152.                     System.out.println(ip+"....离开聊天室");  
  153.                     rese.close();  
  154.                     break;  
  155.                 }  
  156.                   
  157.                 System.out.println("ip: "+ip+"   data: "+data);  
  158.                   
  159.             } catch (IOException e) {  
  160.                 // TODO Auto-generated catch block  
  161.                 e.printStackTrace();  
  162.             }  
  163.         }  
  164.     }     
  165. }  

9、bindExcetion绑定异常。端口被使用了

10、192.168.1.0是网络地址;192.168.1.255是广播地址;

11、TCP传输

Socket和ServerSocket

建立客户端和服务器端

建立连接后,通过Socket中的IO流进行数据的传输

关闭socket

同样,客户端与服务器端是两个独立的应用程序。

演示tcp的传输的的客户端和服务端的互访。

[java]  view plain copy print ?
  1. /*   
  2.    
  3. 需求:客户端给服务端发送数据,服务端收到数据后,给客户端反馈信息。   
  4.   客户端:   
  5. 1.建立socket服务,指定要连接的主机和端口   
  6. 1.获取Socket流中的输出流,将数据写入到该流中,通过网络发送给服务端。   
  7. 3.获取socket流中的输入流,将服务端反馈的数据获取到,并打印,   
  8. 4.关闭客户端资源。   
  9. */    
  10.    
  11. import java.net.*;  
  12. import java.lang.Exception;  
  13. import java.io.*;  
  14.     
  15. class  Client  
  16. {  
  17.     public static void main(String[] args) throws Exception  
  18.     {  
  19.         Socket s = new Socket("127.0.0.1",10086);   
  20.         OutputStream ops = s.getOutputStream();  
  21.   
  22.         ops.write("服务器你好".getBytes());  
  23.           
  24.         InputStream ips = s.getInputStream();  
  25.         byte[] buf = new byte[1024];  
  26.         int len = ips.read(buf);  
  27.         System.out.println(new String(buf,0,len));  
  28.   
  29.         s.close();  
  30.     }  
  31. }  
  32. class Server  
  33. {  
  34.     public static void main(String[] args)throws Exception  
  35.     {  
  36.         ServerSocket ss = new ServerSocket(10086);  
  37.         Socket s = ss.accept();  
  38.   
  39.         InputStream ips = s.getInputStream();  
  40.         byte[] buf = new byte[1024];  
  41.         int len = ips.read(buf);  
  42.   
  43.         System.out.println(s.getInetAddress().toString()+"-----connecting");  
  44.   
  45.         System.out.println(new String(buf,0,len));  
  46.   
  47.         OutputStream ops = s.getOutputStream();  
  48.         Thread.sleep(5000);  
  49.         ops.write("哥们,我收到了".getBytes());  
  50.   
  51.         s.close();  
  52.   
  53.   
  54.     }  
  55. }  

示例代码:需求:键盘录入数据通过服务端转成大写形式。

[java]  view plain copy print ?
  1. /*  
  2. 建立一个文本转换服务器。  
  3. 客户端给服务端发送文本,服务端会将文本转成大写再返回给客户端。  
  4. 而且,客户端可以不断的进行文本转换。当客户端输入over,转换就结束。  
  5.   
  6. 分析:  
  7. 客户端:  
  8. 既然是操作设备上的数据,那么就可以使用io技术,并按照IO的操作规律来思考。  
  9. 源:键盘录入  
  10. 目的:网络设备,也就是网络输出流,  
  11. 而且操作的是文本数据,可以选择字符流。  
  12.   
  13. 步骤:  
  14. 1,建立服务  
  15. 2.获取键盘录入  
  16. 3,将数据发给服务端。  
  17. 4.获取服务端返回的大写数据。  
  18. 5.结束,关闭资源。  
  19.   
  20. 都是文本数据,可以使用字符流进行操作。同时提高效率,要加入缓冲。  
  21.  
  22. */  
  23.   
  24. /*练习总结:这个也借鉴了毕老师和一位写的很优秀的博客。 
  25. 仔细分析使用缓冲流和打印流的区别才发现有很大不同。下面的代码有注解,可以随时复习。真想说,多么好的打印流啊 
  26. */  
  27. import java.net.*;  
  28. import java.lang.Exception;  
  29. import java.io.*;  
  30.   
  31. class  Client1  
  32. {  
  33.     public static void main(String[] args) throws Exception  
  34.     {  
  35.         Socket s = new Socket("127.0.0.1",10086);  
  36.         //输入流封装成对象  
  37.         BufferedReader bur =   
  38.             new BufferedReader(new InputStreamReader(System.in));  
  39.       
  40.         //定义一个socket读取流,读取服务端返回的信息。    
  41.         BufferedReader bure =  
  42.             new BufferedReader(new InputStreamReader(s.getInputStream()));  
  43.   
  44.         //定义目的,将数据写入socket输出流,发给服务器。    
  45.         //BufferedWriter bufOut =     
  46.             //new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));    
  47.   
  48.         PrintWriter pw =new PrintWriter(s.getOutputStream(),true);  
  49.   
  50.         String line = null;  
  51.   
  52.         while((line = bur.readLine())!=null){//阻塞位置1,等待键盘录入,没有数据则等待   
  53.             if("over".equals(line)){  
  54.                 s.close();  
  55.                 break;  
  56.             }     
  57.             //bufOut.write(line);    
  58.             //bufOut.newLine();//没有这一句,则阻塞2的readline不会返回字符,    
  59.             //bufOut.flush();//没有这一句,则数据留在缓冲区中,阻塞2同样阻塞。    
  60.             //pw.write(line+"\r\n");  
  61.             pw.println(line);//println的效果很有意思,它是将数据write写入到流中,并且在对方的控制台打印!一句顶上边三句,也不用在line后加换行符了  
  62.             //pw.flush();//b不是必须刷,因为new PrintWriter(s.getOutputStream(),true);调用println的时候会自动刷新  
  63.             
  64.             String l = bure.readLine();//阻塞位置3,想readLine接收的数据必须有换行符,要么加"\r\n"要么newline()。要么用打印流的换行打印  
  65.               
  66.             System.out.println("server:"+l);    
  67.         }  
  68.   
  69.           
  70.           
  71.         s.close();//这个流关了,其他源自于他的也都关了  
  72.           
  73.         bur.close();  
  74.           
  75.     }  
  76. }  
  77. class Server1  
  78. {  
  79.     public static void main(String[] args) throws Exception{  
  80.         ServerSocket sso = new ServerSocket(10086);  
  81.         Socket s = sso.accept();  
  82.   
  83.         System.out.println(s.getInetAddress().toString()+"---connecting");  
  84.   
  85.          //目的,socket输出流,将大写数据写入到socket输出流,并发送给客户端。    
  86.         //BufferedWriter bufOut =    
  87.             //new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));    
  88.         PrintWriter pw =   
  89.             new PrintWriter(s.getOutputStream(),true);// 通过现有的 OutputStream 创建新的 PrintWriter。调用println的时候会自动刷新  
  90.         //读取socket读取流中的数据。   
  91.         BufferedReader bur =  
  92.             new BufferedReader(new InputStreamReader(s.getInputStream()));  
  93.         String line =null;  
  94.         while((line = bur.readLine())!=null){//阻塞位置2,没有数据+换行符(win中是“\r\n”)则等待,尤其注意换行符   
  95.             System.out.println("收到客户端发的数据:"+line);   
  96.             //pw.println("收到客户端发的数据:"+line);  
  97.             //bufOut.write(line.toUpperCase());    
  98.             //bufOut.newLine();    
  99.             //bufOut.flush();    
  100.             String l = line.toUpperCase();  
  101.               
  102.             pw.println(l);  
  103.             //pw.write(l+"\r\n");  
  104.              
  105.             //pw.flush();  
  106.   
  107.         }  
  108.         sso.close();  
  109.         }  
  110. }  

示例代码:上传图片(使用IO字节流)


[java]  view plain copy print ?
  1. /*  
  2.  需求:上传图片  
  3. */    
  4. /*  
  5. 客户端:  
  6. 1.服务端点  
  7. 2.读取客户端已有的图片数据  
  8. 3.通过socket的输出流将数据发给服务端。  
  9. 4.读取服务端反馈信息。  
  10. 5.关闭。  
  11. */    
  12.     
  13. import java.io.*;    
  14. import java.net.*;    
  15.     
  16. class  PicClient1    
  17. {    
  18.     public static void main(String[] args) throws Exception    
  19.     {    
  20.         Socket s = new Socket("192.168.1.13",10086);    
  21.         FileInputStream fis = new FileInputStream(".d:\\123.jpg");    
  22.     
  23.         OutputStream out = s.getOutputStream();    
  24.     
  25.         byte [] buf = new byte[1024];    
  26.     
  27.         int len = 0;    
  28.     
  29.         while((len=fis.read(buf))!=-1)    
  30.         {    
  31.             out.write(buf,0,len);    
  32.         }    
  33.         //告诉服务端已写完数据    
  34.         s.shutdownOutput();    
  35.     
  36.         InputStream in = s.getInputStream();    
  37.         byte [] bufIn = new byte[1024];    
  38.         int inLen = in.read(buf);    
  39.         System.out.println("Server:"+new String(buf,0,inLen));    
  40.     
  41.         fis.close();    
  42.         s.close();    
  43.     }    
  44. }    
  45.     
  46.     
  47. /*  
  48. 服务端:  
  49. */    
  50. class  PicServer1    
  51. {    
  52.     public static void main(String[] args) throws Exception    
  53.     {    
  54.         ServerSocket ss = new ServerSocket(10086);    
  55.         Socket s = ss.accept();    
  56.         String ip = s.getInetAddress().getHostAddress();    
  57.         System.out.println(ip+"......connected!");    
  58.     
  59.         InputStream in = s.getInputStream();    
  60.         FileOutputStream fos = new FileOutputStream("d:\\321JPG");    
  61.     
  62.         byte[] buf = new byte[1024];    
  63.     
  64.         int len = 0;    
  65.         while((len = in.read(buf))!=-1)    
  66.         {    
  67.             fos.write(buf,0,len);    
  68.         }    
  69.     
  70.         OutputStream out = s.getOutputStream();    
  71.         out.write("上传图片成功".getBytes());    
  72.     
  73.         fos.close();    
  74.         s.close();    
  75.         ss.close();//服务一次就结束    
  76.     }    
  77. }    

TCP客户端并发访问

客户端并发访问服务器时,把服务端的处理代码封装在Runnable实现子类的run方法中,并把服务器获的的Socket对象传给该实现子类的构造函数。

服务端通过while循环启动多个线程,对多个客户端请求进行并发处理。这也是一般服务器的基本原理。


[java]  view plain copy print ?
  1. 上传图片(多客户端并发访问)  
  2. import java.io.*;    
  3. import java.net.*;    
  4.     
  5. /*  
  6. 客户端  
  7. */    
  8.     
  9. class  PicClient    
  10. {    
  11.     public static void main(String[] args) throws Exception    
  12.     {    
  13.     //过滤连接    
  14.         //限定java命令传入的参数只能有1个    
  15.         if(args.length!=1)//    
  16.         {    
  17.             System.out.println("请选择一个jpg格式的图片");    
  18.             return;    
  19.         }    
  20.         //判断文件是否是一个存在的文件(不是目录)。    
  21.         File file = new File(args[0]);    
  22.         if(!(file.exists() && file.isFile()))    
  23.         {    
  24.             System.out.println("该文件有问题,要么不存在,要么不是文件");    
  25.             return;    
  26.         }    
  27.         //判断这个文件的后缀名是不是.JPG    
  28.         if(!file.getName().endsWith(".JPG"))    
  29.         {    
  30.             System.out.println("图片格式错误,请重新选择");    
  31.             return;    
  32.         }    
  33.         //限定文件大小在5M以内    
  34.         if(file.length()>1024*1024*5)    
  35.         {    
  36.             System.out.println("文件过大,没安好心");    
  37.             return;    
  38.         }    
  39.     
  40.         Socket s = new Socket("192.168.1.13",10007);    
  41.         FileInputStream fis = new FileInputStream(file);    
  42.         OutputStream out = s.getOutputStream();    
  43.         byte [] buf = new byte[1024];    
  44.         int len = 0;    
  45.         while((len=fis.read(buf))!=-1)    
  46.         {    
  47.             out.write(buf,0,len);    
  48.         }    
  49.         //告诉服务端已写完数据    
  50.         s.shutdownOutput();    
  51.     
  52.         InputStream in = s.getInputStream();    
  53.         byte [] bufIn = new byte[1024];    
  54.         int inLen = in.read(buf);    
  55.         System.out.println("Server:"+new String(buf,0,inLen));    
  56.     
  57.         fis.close();    
  58.         s.close();    
  59.     }    
  60. }    
  61.     
  62.     
  63. /*  
  64. 服务端:  
  65.   
  66. 这个服务端有个局限性,当A客户端连接上以后,被服务端获取到,服务端执行具体流程。  
  67. 这时B客户端连接,只有等待。因为服务端还没有处理完A客户端的请求。还没有循环回来  
  68. 执行下次accept方法。所以,暂时获取不到B客户端对象。那么为了可以让多个客户端  
  69. 同时并发访问服务端。那么服务端最好就是将每个客户端封装到一个单独的线程中去。这  
  70. 样就可以同时处理多个客户端请求。如何定义线程?只要明确了每一个客户端要在服务端  
  71. 执行的代码即可。将该代码存入run方法中。  
  72.   
  73. */    
  74.     
  75. class  PicServer    
  76. {    
  77.     public static void main(String[] args) throws Exception    
  78.     {    
  79.         ServerSocket ss = new ServerSocket(10007);    
  80.             
  81.         while(true)    
  82.         {    
  83.             Socket s = ss.accept();//如果没有客户端,就阻塞。    
  84.             new Thread(new PicThread(s)).start();    
  85.         }    
  86.             
  87.     }    
  88. }    
  89. class PicThread implements Runnable    
  90. {    
  91.     private Socket s;    
  92.     PicThread(Socket s)    
  93.     {    
  94.         this.s = s;    
  95.     }    
  96.     public void run()    
  97.     {    
  98.         String ip = s.getInetAddress().getHostAddress();    
  99.         int count = 0;    
  100.         try    
  101.         {               
  102.             System.out.println(ip+"......connected!");    
  103.     
  104.             InputStream in = s.getInputStream();    
  105.     
  106.             File file = new File(ip+"("+(count)+")"+".JPG");    
  107.             while(file.exists())    
  108.                 file = new File(ip+"("+(count++)+")"+".JPG");//注意new File并不在磁盘上创建文件。    
  109.     
  110.     
  111.             FileOutputStream fos = new FileOutputStream(file);    
  112.     
  113.             byte[] buf = new byte[1024];    
  114.     
  115.             int len = 0;    
  116.             while((len = in.read(buf))!=-1)    
  117.             {    
  118.                 fos.write(buf,0,len);    
  119.             }    
  120.     
  121.             OutputStream out = s.getOutputStream();    
  122.             out.write("上传图片成功".getBytes());    
  123.     
  124.             fos.close();    
  125.             s.close();    
  126.         }    
  127.         catch (Exception e)    
  128.         {    
  129.             throw new RuntimeException(ip+"上传失败");    
  130.         }    
  131.             
  132.     }    
  133. }    

示例代码7:客户端并发登陆

最多就登陆三次。 


[java]  view plain copy print ?
  1. /*  
  2. 客户端通过键盘录入用户名:  
  3. 服务端对这个用户名进行校验。  
  4.   
  5. 如果该用户存在,在服务器端显示***,已登录。  
  6. 并在客户端显示:***,欢迎光临。  
  7.   
  8. 如果该用户不存在,在服务器端显示 ***,尝试登陆  
  9. 并在客户端显示 ***,该用户不存在。  
  10.   
  11. 最多就登陆三次。  
  12. */    
  13. import java.io.*;    
  14. import java.net.*;    
  15.     
  16. /*  
  17. 客户端:  
  18. */    
  19. class  LoginClient    
  20. {    
  21.     public static void main(String[] args) throws Exception    
  22.     {    
  23.         Socket s = new Socket("192.168.1.13",10010);        
  24.             
  25.         BufferedReader bufr =    
  26.             new BufferedReader(new InputStreamReader(System.in));    
  27.     
  28.         PrintWriter out = new PrintWriter(s.getOutputStream(),true);    
  29.     
  30.         BufferedReader in =     
  31.             new BufferedReader(new InputStreamReader(s.getInputStream()));    
  32.     
  33.             
  34.         for(int x =0;x<3;x++)    
  35.         {    
  36.             String line =bufr.readLine();    
  37.             if(line==null)    
  38.                 break;    
  39.             out.println(line);    
  40.     
  41.             String info = in.readLine();    
  42.             System.out.println("info:"+info);    
  43.             if(info.contains("欢迎"))    
  44.                 break;              
  45.         }    
  46.     
  47.         bufr.close();    
  48.         s.close();    
  49.     
  50.     }    
  51. }    
  52. /*  
  53. 服务端:  
  54. */    
  55. class  LoginServer    
  56. {    
  57.     public static void main(String[] args) throws Exception    
  58.     {    
  59.         ServerSocket ss = new ServerSocket(10010);    
  60.         while(true)    
  61.         {    
  62.             Socket s = ss.accept();    
  63.             new Thread(new LoginThread(s)).start();    
  64.         }       
  65.     }    
  66. }    
  67. class LoginThread implements Runnable    
  68. {    
  69.     private Socket s;    
  70.     LoginThread(Socket s)    
  71.     {    
  72.         this.s = s;    
  73.     }    
  74.     public void run()    
  75.     {    
  76.         String ip =s.getInetAddress().getHostAddress();    
  77.         System.out.println(ip+".....connected");    
  78.         try    
  79.         {    
  80.             for(int x =0;x<3;x++)    
  81.             {    
  82.                 BufferedReader in =     
  83.                     new BufferedReader(new InputStreamReader(s.getInputStream()));    
  84.                     
  85.                 String name = in.readLine();    
  86.                 if(name==null)    
  87.                     break;    
  88.     
  89.                 BufferedReader bufr =    
  90.                     new BufferedReader(new FileReader("user.txt"));    
  91.                 PrintWriter out = new PrintWriter(s.getOutputStream(),true);    
  92.                     
  93.                 boolean flag = false;    
  94.     
  95.                 String line =null;    
  96.                 while((line=bufr.readLine())!=null)    
  97.                 {    
  98.                     if(line.equals(name))    
  99.                     {    
  100.                         flag = true;    
  101.                         break;    
  102.                     }    
  103.                 }    
  104.     
  105.                 if(flag)    
  106.                 {    
  107.                     System.out.println(name+"已登录");    
  108.                     out.println(name+",欢迎光临");    
  109.                     break;    
  110.                 }    
  111.                 else    
  112.                 {    
  113.                     System.out.println(name+",尝试登录");    
  114.                     out.println(name+",用户名不存在");    
  115.                 }    
  116.             }               
  117.             s.close();    
  118.         }    
  119.         catch (Exception e)    
  120.         {    
  121.             throw new RuntimeException(ip+":校验失败");    
  122.         }    
  123.     }       
  124. }    

浏览器客户端与自定义服务器

 

浏览器也是一个客户端,它可以对HTML进行解析。

Dos下的telnetwindow提供的远程登陆客户端,命令“telnet  ip 地址 口号”可以用连接到网络上的任意一台主机。

Tomcat服务器:默认使用的是8080端口,启动Tomcat服务器,在浏览器是输入“本地地址:8080”就可以看到Tomcat的主页。

 

 

[java]  view plain copy print ?
  1. /*  
  2. 演示客户端和服务端。  
  3. 1.客户端:浏览器。  
  4. 服务端:自定义  
  5.   
  6.   
  7. 2.  
  8. 客户端是浏览器  
  9. 服务端:TomCat服务器。  
  10.   
  11. 3.  
  12. 客户端:自定义  
  13. 服务器:TomCat服务器。  
  14.   
  15. */    
  16. import java.net.*;    
  17. import java.io.*;    
  18. class ServerDemo     
  19. {    
  20.     public static void main(String[] args) throws Exception    
  21.     {    
  22.         ServerSocket ss = new ServerSocket(11000);    
  23.     
  24.         Socket s = ss.accept();    
  25.         String ip = s.getInetAddress().getHostAddress();    
  26.         System.out.println(ip+"....connected");    
  27.     
  28.         InputStream in = s.getInputStream();    
  29.     
  30.         byte[] buf = new byte[1024];    
  31.         int len = in.read(buf);    
  32.         System.out.println(new String(buf,0,len));    
  33.     
  34.         PrintWriter out = new PrintWriter(s.getOutputStream(),true);    
  35.             
  36.         out.println("<font color ='red' size = '10'>客户端你好");    
  37.     
  38.         s.close();    
  39.         ss.close();    
  40.     
  41.     }    
  42. }    
  43.   
  44. import java.io.*;    
  45. import java.net.*;    
  46.     
  47. class MyIE     
  48. {    
  49.     public static void main(String[] args) throws Exception    
  50.     {    
  51.         //浏览器内部建立Socket客户端    
  52.         Socket s = new Socket("192.168.1.13",8080);    
  53.         //想服务器发送请求消息头    
  54.         PrintWriter out = new PrintWriter(s.getOutputStream(),true);//别忘了加true    
  55.         out.println("GET /myweb/demo.html HTTP/1.1");    
  56.         out.println("Accept: */*");    
  57.         out.println("Accept-Language: zh-cn");    
  58.         out.println("Host: 192.168.1.13:11000");    
  59.         out.println("Connection: Keep-Closed");    
  60.         out.println();    
  61.         out.println();//请求消息头末尾一定要有一行空行。    
  62.             
  63.         System.out.println("over1");    
  64.         //读取服务器发送过来的响应消息头和数据体。    
  65.         BufferedReader bufr =     
  66.             new BufferedReader(new InputStreamReader(s.getInputStream()));    
  67.         String line = null;    
  68.         while((line=bufr.readLine())!=null)    
  69.         {    
  70.             System.out.println(line);    
  71.         }    
  72.     
  73.         s.close();    
  74.     
  75.     }    
  76. }    
  77. /*    
  78. http://192.168.1.13:11000/myweb/demo.html    
  79.     
  80. 客户端http请求消息头,    
  81. /*GET / HTTP/1.1  
  82. Accept: text/html, application/xhtml+xml,   
  83. Accept-Language: zh-CN  
  84. User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)  
  85. Accept-Encoding: gzip, deflate  
  86. Host: 192.168.12.101:10086  
  87. Connection: Keep-Alive  
  88. */    
  89.      
  90. /*   
  91.    
  92. 服务器:HTTP响应消息头   
  93. HTTP/1.1 200 OK   
  94. Server: Apache-Coyote/1.1   
  95. Accept-Ranges: bytes   
  96. ETag: W/"315-1358328614234"   
  97. Last-Modified: Wed, 16 Jan 2013 09:30:14 GMT   
  98. Content-Type: text/html   
  99. Content-Length: 315   
  100. Date: Wed, 16 Jan 2013 10:03:30 GMT   

URL

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

URI 是统一资源标识符,而 URL是统一资源定位符。因此,笼统地说,每个 URL都是 URI,但不一定每个 URI都是 URL。这是因为 URI还包括一个子类,即统一资源名称 (URN),它命名资源但不指定如何定位资源。

常用方法示例:

intgetDefaultPort() :获取与此 URL关联协议的默认端口号。

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

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

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

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

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

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

[java]  view plain copy print ?
  1. import java.net.*;    
  2. class  URLDemo    
  3. {    
  4.     public static void main(String[] args) throws Exception    
  5.     {    
  6.         //URL url=new URL("http://192.168.1.13:11000/myweb/demo.html");    
  7.         URL url=new URL("http://192.168.1.13:11000/myweb/demo.html?name=haha&age=30");    
  8.         System.out.println("getProtocol():"+url.getProtocol()); //http              
  9.         System.out.println("getHost():"+url.getHost());//192.168.1.13    
  10.         System.out.println("getDefaultPort():"+url.getDefaultPort());//80,如果关联的协议没有默认的端口,则值为-1;    
  11.         System.out.println("getPort():"+url.getPort()); //  11000,如果没有设置则为-1;    
  12.         System.out.println("getPath():"+url.getPath());// /myweb/demo.html    
  13.         System.out.println("getFile():"+url.getFile());///myweb/demo.html?name=haha&age=30    
  14.         System.out.println("getQuery():"+url.getQuery());//name=haha&age=30    
  15.     
  16.     /*  int port = url.getPort();  
  17.         if(port==-1)  
  18.             port =80;  
  19.         getPort() = -1  
  20.     */    
  21.     }    
  22. }    

域名解析

Ip地址登陆网站是,不好记忆,人们习惯用主机名。从主机名到获得该主机名对应的Ip地址的过程,就是域名解析。域名解析一般是DNS服务器完成的。

域名解析主要分为两步:

第一步:查找本地的Ip地址和主机名映射表。

这个表,在C:\Windows\System32\drivers\etc文件夹中的hosts文件。127.0.01localhost的对应关系就在这个表中。

hosts文件进行设置可以实现一些功能,比如:破解,将软件的官网地址域名与127.0.0.1对应;过滤垃圾网站、恶意网站。

第二步:如果第一步没有找到,那么就去你设置的DNS服务器中去查找映射表,找到对应的IP地址。获得IP地址后,再与之连接。

 


------------android培训java培训、期待与您交流! -------------


 

谁想学java我这有视频,最近几个月一直在看java基础知识,是传智与CSDN合作推出的视频
打开链接点上方的进入黑马学科,老师讲课很幽默,深入浅出、容易理解

点击打开链接   java全套视频
   
点击打开链接 全世界最适合0基础学习编程的网上校园
点击打开链接  .Net全套视频
点击打开链接 PHP全套视频

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值