java网络编程(套接字)

套接字是java提供一套进行网络通信的API---TCP/UDP;

ISO七层模型

  物理层数据链路层传输层-IP、 网络层-UDP/TCP 、会话层 、 表示层、 应用层 ---HTTP FTP POP3 SMTP...

IP地址:在网络中标识计算机地址的---IPv4---用四组整数(0-255)标识一个IP地址---123.125.43.11---IPv6

端口号: 用于指定接收或者发送消息的端口---0-65535---0-1024被计算机内部占用

 

UDP

  基于流的,不需要建立连接,不可靠,会对数据进行封包,每个包是64k大小,传输效率是比较高。例如直播

  java提供了一套套接字用于UDP通信:

    1.InetSocketAddress("IP地址",端口号):表示IP地址和端口号;

    2.DatgramSocket():用来发送和接收数据包的套接字;

    3.DatagramPacket(byte[] buf, int length, SocketAddress address):用来对数据封包,以便传输;

  发送端基本步骤:

    1.创建发送数据套接字对象;

    2.创建目的地的IP地址和发送端口;

    3.将数据封包;

    4.发送(send(DatagramPacket  dp)方法);

    5.关闭套接字(close());

  接收端基本步骤:

    1.创建接收数据的套接字对象并绑定接收数据的端口;

    2.创建数据封包用来储存数据;

    3.接收数据(receive(DatagramPacket  dp));

    4.关闭套接字(close());

 

 1 import java.net.DatagramPacket;
 2 import java.net.DatagramSocket;
 3 import java.net.InetSocketAddress;
 4 import java.util.Scanner;
 5 
 6 public class UDPChatDemo {
 7 
 8     public static void main(String[] args) {
 9 
10         new Thread(new Sender()).start();
11         new Thread(new Receiver()).start();
12     }
13 
14 }
15 
16 // 发送端
17 class Sender implements Runnable {
18 
19     @SuppressWarnings("resource")
20     @Override
21     public void run() {
22 
23         try {
24             // 准备套接字对象
25             DatagramSocket ds = new DatagramSocket();
26 
27             // 创建一个地址对象
28             InetSocketAddress isa = new InetSocketAddress("localhost", 9527);
29 
30             // 从控制台来获取数据
31             Scanner s = new Scanner(System.in);
32 
33             while (true) {
34                 String msg = s.nextLine();
35 
36                 // 将数据封包
37                 DatagramPacket dp = new DatagramPacket(msg.getBytes(), msg.getBytes().length, isa);
38 
39                 // 发送数据
40                 ds.send(dp);
41 
42                 // 判断这个语句是否是exit
43                 if (msg == "exit" || msg != null && msg.equals("exit")) {
44                     break;
45                 }
46             }
47 
48         } catch (Exception e) {
49             e.printStackTrace();
50         }
51 
52     }
53 
54 }
55 
56 class Receiver implements Runnable {
57 
58     @SuppressWarnings("resource")
59     @Override
60     public void run() {
61 
62         try {
63             // 准备套接字对象,绑定端口号
64             DatagramSocket ds = new DatagramSocket(9527);
65 
66             // 准备数据包
67             DatagramPacket dp = new DatagramPacket(new byte[1024], 1024);
68 
69             while (true) {
70 
71                 // 接收数据
72                 ds.receive(dp);
73 
74                 // 获取数据
75                 String msg = new String(dp.getData(), 0, dp.getLength());
76                 if (msg == "exit" || msg != null && msg.equals("exit")) {
77                     break;
78                 }
79 
80                 // 获取地址
81                 System.out.print(dp.getAddress() + ":");
82                 System.out.println(msg);
83             }
84 
85         } catch (Exception e) {
86             e.printStackTrace();
87         }
88 
89     }
90 
91 }

 

 

 

 

TCP

 

  基于流的,需要建立连接,经过了三次握手,理论上不限制数据的大小,传输速率比较低。例如文件的传输

  java提供的套接字:

    Socket:客户端套接字

    ServerSocket:服务器端套接字

  客户端基本步骤:

    1.创建客户端套接字对象;

    2.发起连接,并绑定连接地址;

    3.获取输出流,写出数据;

    4.通知服务器端数据写出完毕;

    5.关闭套接字

 

 1 import java.io.InputStream;
 2 import java.io.OutputStream;
 3 import java.net.InetSocketAddress;
 4 import java.net.Socket;
 5 
 6 public class TCPClientDemo2 {
 7 
 8     public static void main(String[] args) throws Exception {
 9 
10         // 创建客户端的套接字
11         Socket s = new Socket();
12 
13         // 发起连接,绑定端口号
14         s.connect(new InetSocketAddress("localhost", 8980));
15 
16         // 获取输出流
17         OutputStream out = s.getOutputStream();
18 
19         // 写出数据
20         out.write("我来啦啦啦~~~".getBytes());
21 
22         // 关闭输出流
23         s.shutdownOutput();
24 
25         // 获取输入流
26         InputStream in = s.getInputStream();
27 
28         // 读取数据
29         byte[] bs = new byte[1024];
30         int len = -1;
31         while ((len = in.read(bs)) != -1) {
32             System.out.println(new String(bs, 0, len));
33         }
34 
35         // 通知服务器端数据已经读取完毕
36         s.shutdownInput();
37 
38         // 关闭套接字
39         s.close();
40 
41     }
42 
43 }

 

 

 

  服务器端基本步骤:

    1. 创建服务器端套接字,绑定端口号

 

    2. 接受连接,获取到一个Socket对象

 

    3. 获取输入流,读取数据

 

    4. 通知客户端数据读取完毕

 

    5. 关闭套接字

 

 

 1 import java.io.InputStream;
 2 import java.net.ServerSocket;
 3 import java.net.Socket;
 4 
 5 public class TCPServerDemo {
 6 
 7     public static void main(String[] args) throws Exception {
 8 
 9         // 创建一个服务器端套接字对象---绑定端口号
10         ServerSocket ss = new ServerSocket(9999);
11 
12         // 接受连接
13         Socket s = ss.accept();
14 
15         // 获取一个输入流
16         InputStream is = s.getInputStream();
17 
18         // 读取数据
19         byte[] bs = new byte[1024];
20         int len = -1;
21         while ((len = is.read(bs)) != -1) {
22             System.out.println(new String(bs, 0, len));
23         }
24 
25         // 通知客户端数据读取完毕
26         s.shutdownInput();
27 
28         // 关闭套接字
29         s.close();
30         ss.close();
31 
32     }
33 
34 }

 

注意:receive/connect/accept/read/write都会产生阻塞

 

posted @ 2017-05-09 20:05  大大大圣  阅读(1129)  评论(0编辑  收藏  举报