黑马Java学习笔记之-----网络编程

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

 

IP地址:

格式:IP地址网络地址+主机地址 (IP地址使用32位长度二进制数据表示)

网络号:用于识别主机所在的网络。

主机号:用于识别该网络中的主机。

IP地址分为5类,A类保留给政府机构,B类分配给中等规模的公司,C类分配给任何需要的人,D类用于组播,E类用于实验。IP地址的范围:

 

InetAddress类:

主要表示IP地址,包括:Inet4AddressInet6Address

 

 1   //测试InetAddress类
 2   
 3   import java.net.InetAddress;
 4   
 5   public class InetAddressTest
 6   {
 7       public static void main(String[] args)throws Exception   //抛出异常
 8       {
 9           testInet();
10       }
11   
12       public static void testInet()throws Exception  //抛出异常
13       {
14           InetAddress localAdd = InetAddress.getLocalHost();   //实例化InetAddress类
15           InetAddress remoteAdd = InetAddress.getByName("www.baidu.com");
16           System.out.println("本机ip:"+localAdd.getHostAddress());  //得到本地Ip地址
17           System.out.println("百度ip:"+remoteAdd.getHostAddress()); //得到远程IP地址
18           System.out.println("本机是否可达:"+localAdd.isReachable(5000)); //判断地址是否可达,同时指定超时时间
19       }
20   }

 

TCPUDP

UDP

1. 将数据源和目的封装成数据包,不需要建立连接。

2. 每个数据报的大小限制在64k内。

3. 因无连接,是不可靠协议。

4. 不需要建立连接,速度快。

TCP

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

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

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

4. 必须建立连接,效率稍低。

注:三次握手:

第一次:我问你在么?

第二次:你回答在。

第三次:我反馈哦我知道你在。

 

Socket(UDP传输)

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

2. 通信的两端都有Socket

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

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

 

 

()UDP传输:

 

DatagramSocket

 

构造:DatagramSocket()
             构造数据报套接字并将其绑定到本地主机上任何可用的端口。

 

  DatagramSocket(int port)
          创建数据报套接字并将其绑定到本地主机上的指定端口。

 

方法:void receive(DatagramPacket p)
             从此套接字接收数据报包。

 

  void send(DatagramPacket p)
          从此套接字发送数据报包。

 

  void close()
          关闭此数据报套接字。

 

DatagramPacket

 

构造:

 

DatagramPacket(byte[] buf, int length)
      构造 DatagramPacket,用来接收长度为 length 的数据包。

 

DatagramPacket(byte[] buf, int length, InetAddress address, int port)
      构造数据报包,用来将长度为 length 的包发送到指定主机上的指定端口号。

 

方法:

 

InetAddress  getAddress()
   返回某台机器的 IP 地址,此数据报将要发往该机器或者是从该机器接收到的。

 

byte[]  getData()
          返回数据缓冲区。

 

int getLength()
          返回将要发送或接收到的数据的长度。

 

int getPort()
          返回某台远程主机的端口号,此数据报将要发往该主机或者是从该主机接收到的。

 1 //udp 发送端
 2 import java.net.*;
 3 public class UdpSend  
 4 {
 5     public static void main(String[] args) throws Exception
 6     {
 7         //1. 创建udp socket,建立端点,随机端口
 8         DatagramSocket ds = new DatagramSocket();
 9         //2. 确定数据,并封装成数据包
10         String str = "HelloWorld!";
11         byte[] buf = str.getBytes();
12         DatagramPacket dp = new DatagramPacket(buf, buf.length, InetAddress.getByName("192.168.1.101"), 3344);
13         //3. 通过DatagramSocket的send方法,将数据包dp发送出去,
14         ds.send(dp);
15         //4. 关闭资源
16         ds.close();
17     }
18 } 1 //udp 接收端
 2 import java.net.*;
 3 public class UdpReceive 
 4 {
 5     public static void main(String[] args) throws Exception
 6     {
 7         //1. 创建udp socket,建立断点,并指定端口
 8         DatagramSocket ds = new DatagramSocket(3344);
 9 
10         //2. 定义数据包,用于存储数据
11         byte[] buf = new byte[1024];
12         DatagramPacket dp = new DatagramPacket(buf,buf.length);
13 
14         //3. 通过DatagramSocket中的receive方法将收到的数据存入数据包dp中
15         ds.receive(dp);     //receive为阻塞式方法。
16 
17         //4. 通过DatagramPacket中的方法获取数据包dp中的数据
18         String ip = dp.getAddress().getHostAddress();
19         byte[] buff = dp.getData();
20         int length = dp.getLength();
21         String data = new String(buff,0,length);
22         int port = dp.getPort();
23         System.out.println(ip+"::"+data+"::"+port);
24 
25         //5. 关闭资源
26         ds.close();
27     }
28  1 /*
  2 编写一个聊天程序。
  3 有收数据的部分,和发数据的部分。
  4 这两部分需要同时执行。
  5 那就需要用到多线程技术。
  6 一个线程控制收,一个线程控制发。
  7 
  8 因为收和发动作是不一致的,所以要定义两个run方法。
  9 而且这两个方法要封装到不同的类中。
 10 */
 11 
 12 import java.io.*;
 13 import java.net.*;
 14 
 15 class Send implements Runnable  //继承Runnable
 16 {
 17     private DatagramSocket ds;
 18     public Send(DatagramSocket ds)
 19     {
 20         this.ds = ds;
 21     }
 22     public void run()   //发送端
 23     {
 24         try
 25         {
 26             BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
 27             String line = null;
 28             while ((line=br.readLine())!=null)
 29             {
 30 
 31                 byte[] buf = line.getBytes();
 32                 DatagramPacket dp = new DatagramPacket(buf, buf.length, InetAddress.getByName("192.168.1.255"), 3344);
 33                 ds.send(dp);
 34 
 35                 if ("886".equals(line))
 36                 {
 37                     
 38                     break;
 39                 }
 40 
 41             }
 42         }
 43         catch (Exception e)
 44         {
 45             throw new RuntimeException("发送端失败!");
 46         }
 47 
 48         
 49     }
 50 }
 51 
 52 class Rec implements Runnable   //继承Runnable
 53 {
 54     private DatagramSocket ds;
 55     public Rec(DatagramSocket ds)
 56     {
 57         this.ds = ds;
 58     }
 59     public void run()  //接受端
 60     {
 61 
 62         try
 63         {
 64             while (true)
 65             {
 66                 byte[] buf = new byte[1024];
 67                 DatagramPacket dp = new DatagramPacket(buf, buf.length);
 68                 ds.receive(dp);
 69 
 70                 String ip = dp.getAddress().getHostAddress();
 71                 String data = new String(dp.getData(),0,dp.getLength());
 72                 if ("886".equals(data))
 73                 {
 74                     System.out.println(ip+"离开聊天室!");
 75                     break;
 76                 }
 77                 
 78                 System.out.println(ip+"::"+data);
 79             }
 80 
 81         }
 82         catch (Exception e)
 83         {
 84             throw new RuntimeException("接收端失败!");
 85         }
 86         
 87     }
 88 }
 89 
 90 public class ChatDemo  
 91 {
 92     public static void main(String[] args) throws Exception
 93     {
 94         DatagramSocket sendSocket = new DatagramSocket();
 95         DatagramSocket recSocket = new DatagramSocket(3344);
 96         new Thread(new Send(sendSocket)).start();
 97         new Thread(new Rec(recSocket)).start();
 98         
 99     }
100

 

 

(二)TCP传输:

SocketServerSocket

建立客户端和服务器端

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

关闭socket

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

Socket类:

构造方法:

Socket() 

通过系统默认类型的 SocketImpl 创建未连接套接字

Socket(InetAddress address, int port) 

创建一个流套接字并将其连接到指定 IP 地址的指定端口号。

Socket(String host, int port) 

创建一个流套接字并将其连接到指定主机上的指定端口号。

 

 

方法摘要:

void close() 

关闭此套接字。

InetAddress getInetAddress() 

返回套接字连接的地址。

InputStream getInputStream() 

返回此套接字的输入流。

OutputStream getOutputStream() 

返回此套接字的输出流。 

int getPort() 

返回此套接字连接到的远程端口。

void shutdownInput() 

此套接字的输入流置于“流的末尾”。 

void shutdownOutput() 

禁用此套接字的输出流。 

String toString() 

将此套接字转换为 String

 

ServerSocket类:

构造方法:

ServerSocket() 

创建非绑定服务器套接字。 

ServerSocket(int port) 

创建绑定到特定端口的服务器套接字。

方法摘要:

Socket accept() 

侦听并接受到此套接字的连接。

void close() 

关闭此套接字。 

InetAddress getInetAddress() 

返回此服务器套接字的本地地址。

 

TCP传输流程:

(一)客户端:

1. 建立Socket服务,并建立要连接的主机和端口。

2. 获取Socket流中的输出流OutputStream,将数据写入流中,通过网络发送给服务端。

3. 获取Socket流中的输入流InputStream,获取服务端的反馈信息。

4. 关闭资源。

(二)服务端:

1. 建立ServerSocket服务,并监听一个接口。

2. 通过ServerSocket服务的accept方法,获取Socket服务对象。

3. 使用客户端对象的读取流获取客户端发送过来的数据。

4. 通过客户端对象的写入流反馈信息给客户端。

5. 关闭资源。

 1 /*
 2 演示tcp的传输的客户端和服务端的互访。
 3 
 4 需求:客户端给服务端发送数据,服务端收到后,给客户端反馈信息。
 5 
 6 */
 7 
 8 /*
 9 客户端:
10 1,建立socket服务。指定要连接主机和端口。
11 2,获取socket流中的输出流。将数据写到该流中。通过网络发送给服务端。
12 3,获取socket流中的输入流,将服务端反馈的数据获取到,并打印。
13 4,关闭客户端资源。
14 
15 */
16 import java.io.*;
17 import java.net.*;
18 class TcpClient2 
19 {
20     public static void main(String[] args)throws Exception 
21     {
22         Socket s = new Socket("192.168.1.254",10004);
23         
24         OutputStream out = s.getOutputStream();
25 
26         out.write("服务端,你好".getBytes());
27 
28         
29         InputStream in = s.getInputStream();
30 
31         byte[] buf = new byte[1024];
32 
33         int len = in.read(buf);
34 
35         System.out.println(new String(buf,0,len));
36 
37         s.close();
38     }
39 }
40 
41 
42 class TcpServer2
43 {
44     public static void main(String[] args) throws Exception
45     {
46         ServerSocket ss = new ServerSocket(10004);
47 
48         Socket s = ss.accept();
49 
50         String ip = s.getInetAddress().getHostAddress();
51         System.out.println(ip+"....connected");
52         InputStream in = s.getInputStream();
53 
54         byte[] buf = new byte[1024];
55 
56         int len = in.read(buf);
57 
58         System.out.println(new String(buf,0,len));
59 
60 
61         OutputStream out = s.getOutputStream();
62 
63 
64         Thread.sleep(10000);
65         out.write("哥们收到,你也好".getBytes());
66 
67         s.close();
68 
69         ss.close();
70     }
71 }

 

TCP练习:

 

  1 /*
  2 需求:建立一个文本转换服务器。
  3 客户端给服务端发送文本,服务单会将文本转成大写在返回给客户端。
  4 而且客户度可以不断的进行文本转换。当客户端输入over时,转换结束。
  5 分析:
  6 客户端:
  7 既然是操作设备上的数据,那么就可以使用io技术,并按照io的操作规律来思考。
  8 源:键盘录入。
  9 目的:网络设备,网络输出流。
 10 而且操作的是文本数据。可以选择字符流。
 11 步骤
 12 1,建立服务。
 13 2,获取键盘录入。
 14 3,将数据发给服务端。
 15 4,后去服务端返回的大写数据。
 16 5,结束,关资源。
 17 都是文本数据,可以使用字符流进行操作,同时提高效率,加入缓冲。
 18 */
 19 import java.io.*;
 20 import java.net.*;
 21 class  TransClient
 22 {
 23     public static void main(String[] args) throws Exception
 24     {
 25         Socket s = new Socket("192.168.1.254",10005);
 26   //定义读取键盘数据的流对象。
 27         BufferedReader bufr = 
 28             new BufferedReader(new InputStreamReader(System.in));
 29   //定义目的,将数据写入到socket输出流。发给服务端。
 30         //BufferedWriter bufOut = 
 31             //new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
 32         PrintWriter out = new PrintWriter(s.getOutputStream(),true);
 33   
 34   //定义一个socket读取流,读取服务端返回的大写信息。
 35         BufferedReader bufIn = 
 36             new BufferedReader(new InputStreamReader(s.getInputStream()));
 37 
 38         String line = null;
 39         
 40         while((line=bufr.readLine())!=null)
 41         {
 42             if("over".equals(line))
 43                 break;
 44             
 45             out.println(line);
 46 //          bufOut.write(line);
 47 //          bufOut.newLine();
 48 //          bufOut.flush();
 49 
 50             String str =bufIn.readLine();
 51             System.out.println("server:"+str);
 52             
 53         }
 54 
 55         bufr.close();
 56         s.close();
 57 
 58 
 59     }
 60 }
 61 /*
 62 服务端:
 63 源:socket读取流。
 64 目的:socket输出流。
 65 都是文本,装饰。
 66 */
 67 class  TransServer
 68 {
 69     public static void main(String[] args) throws Exception
 70     {
 71         ServerSocket ss = new ServerSocket(10005);
 72 
 73         Socket s = ss.accept();
 74         String ip = s.getInetAddress().getHostAddress();
 75         System.out.println(ip+"....connected");
 76 
 77         //读取socket读取流中的数据。
 78         BufferedReader bufIn =
 79             new BufferedReader(new InputStreamReader(s.getInputStream()));
 80 
 81         //目的。socket输出流。将大写数据写入到socket输出流,并发送给客户端。
 82         //BufferedWriter bufOut = 
 83             //new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
 84 
 85         PrintWriter out = new PrintWriter(s.getOutputStream(),true);
 86 
 87         String line = null;
 88         while((line=bufIn.readLine())!=null)
 89         {
 90 
 91             System.out.println(line);
 92 
 93             out.println(line.toUpperCase());
 94 //          bufOut.write(line.toUpperCase());
 95 //          bufOut.newLine();
 96 //          bufOut.flush();
 97         }
 98 
 99         s.close();
100         ss.close();
101 
102     }
103 }
104 /*该例子出现的问题。
105 现象:客户端和服务端都在莫名的等待。
106 为什么呢?
107 因为客户端和服务端都有阻塞式方法。这些方法么没有读到结束标记。那么就一直等
108 而导致两端,都在等待。
109 */

 

 


 

 

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

 

 

 

posted @ 2013-04-29 02:10  Mercy_K  阅读(192)  评论(0编辑  收藏  举报