Java 网络编程(一)


Java 网络编程(一)

学习了前面的I/O,就要学习Java另一个很重要的知识了:网络

1.   网络基础知识

因为万能的Java把网络操作封装的比较彻底,所以我们比不需要直接和网络底层的东西打交道,不过这里还是介绍一些基础的知识:

1)        OSI网络模型:这个模型把网络通信工作分成7层,这7层分别是物理层、数据链路层、网络层、传输层、会话层、表示层、应用层,层次结构是这样的:

 

2)Java网络通信的三个要素:

a)        IP地址:

IP地址是网络通信中一个设备的唯一标识,在底层是一串32位的二进制数(IPv4),在Java里面是一串点分十进制的字符串,例如”192.168.1.1”等,每一个点隔开的数取值范围是0~255,即20~28-1,有四组,每组可转换成8为二进制数,一共32位。总之一句话,IP地址是用于标识计算机的。

b)        端口号:

现在的计算机都是多任务的,每一个进程都有自己的ID,因此即使我们通过前面的IP地址找到了要找计算机,如果没有端口号也找不到到底吆喝那个应用程序通信,所以呢,端口号就是用来标识一台计算机上的一个应用程序的。具体这个端口号取什么值可以自定义,取值范围是0~65535,即20~216-1。

就上面两点总结一句话:IP地址用来标识计算机,而端口号用来标识应用程序,它们在Java中对应的类是InetSocketAddress,稍后的例子里会说到。

 

c)        传输协议:TCP、UDP

TCP是Transmission Control Protocol (传输控制协议)的简称,是一种面向连接的传输层通信协议;使用TCP协议进行通信时,要通信的两端必须要经过“三次握手”建立连接后才能通信。

UDP是User Datagram Protocol(用户数据包协议)的简称,是一种无连接的传输层通信协议;使用UDP协议进行通信时,是不需要事先建立好连接的,而且UDP协议是不会处理在传输过程中丢失的数据包的,但是他具有资源消耗小、处理速度快的特点。

说到这里就要提一下现在常用的TCP/IP网络模型和上面的OSI网络模型之间的对应关系:


3)        Socket(套接字)

套接字是网络服务为要通信的两个程序提供的一种机制,现在的网络通信基本上都是基于Socket间的通信,两个程序通过Socket的输入输出进行通信。

好了,说了这么多,还是先结合两个简单的例子来说明一下在Java里打的怎么用Socket套接字进行程序间通信吧(网络通信必须要用到前面学习的Java I//O知识哦):

基于TCP连接的例子:

1)        服务器端代码

package learn.net;
 
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
 
/**TCP服务器端程序*/
public class Server {
       /** 初始化服务器 */
       private void initServer() throws IOException {
              /* 创建一个服务端套接字,监听9999端口 */
              ServerSocket welcome_socket = new ServerSocket(9999);
              /* 关闭创建服务端套接字 */
              System.out.println("服务器已启动成功!");
              /* 服务器持续监听来自客户端的请求 */
              while (true) {
<span style="white-space:pre">		</span>     /* 接受来自客户端的请求,线程执行到welcome_socket.accept()时会被挂起,直到接收到客户端发送过来的连接请求 */
                     Socket connection_socket = welcome_socket.accept();
                     /* 创建输入流对象以便接收来自客户端的消息 */
                     InputStream in_from_client = connection_socket.getInputStream();
                     /* 创建输出流对象以便向客户端发送消息 */
                     OutputStream out_to_client = connection_socket.getOutputStream();
                     /*读取客户端发来的消息*/
                     byte[] b = new byte[1024];
                     /* 线程执行到in_from_client.read()时会被挂起,直到接收到客户端发送过来的数据 */
                     int len = in_from_client.read(b);
                     String fromClientText = new String(b, 0, len);
                     System.out.println("来自客户端的消息:" + fromClientText);
                     String toClientText = "客户端你好!";
                     /* 向客户端写入数据 */
                     out_to_client.write(toClientText.getBytes());
                     out_to_client.flush();
              }
       }
 
       /** 测试 */
       public static void main(String[] args) throws Exception {
              Server sever = new Server();
              /* 初始化服务器 */
              sever.initServer();
       }
}


 

2)        客户端代码

package learn.net;
 
import java.net.*;
import java.io.*;
 
/**TCP客户端程序*/
public class Client {
 
       /**初始化客户端*/
       public void initClient() {
              Socket c_socket = null;
              while (true) {
                     try {
                            /*创建套接字*/
                            c_socket = new Socket();
<span style="white-space:pre">			</span>    /*创建一个连接到IP地址为127.0.0.1(也就自本机),端口号为9999的网络套接字地址对象*/
                            InetSocketAddressnetAddress=new InetSocketAddress("127.0.0.1", 9999);
<span style="white-space:pre">			</span>    /*调用套接字的connect()方法连接到netAddress所指向的计算机和应用程序,后面的500为此次连接的超时时间*/
                            c_socket.connect(netAddress, 500);
                            /*获取套接字的输出流以便向服务端发送数据*/
                            OutputStreamout_to_server = c_socket.getOutputStream();
                            /*获取套接字的输入流以便接收服务端发送过来的数据*/
                            InputStreamin_from_server = c_socket.getInputStream();
                            /*输入要发送到服务器的数据*/
                            BufferedReaderfromKeyBoard = new BufferedReader(
                                          newInputStreamReader(System.in));
                            System.out.print("请输入要发送到服务器的消息:");
                            String inputText;
                            inputText = fromKeyBoard.readLine();
                            /*将键盘输入的数据写入到输出流并发送到服务器*/
                            out_to_server.write(inputText.getBytes());
                            out_to_server.flush();
                            /*读取服务器端发送过来的消息*/
                            byte[] b = new byte[1024];
                           
<span style="white-space:pre">			</span>    /*线程执行到in_from_server.read()时会被挂起,直到接收到服务器发送过来的数据*/
                            int len = in_from_server.read(b);
                            String server_msg = new String(b, 0, len);
                            System.out.println("来自服务器的消息:" + server_msg);
                     } catch (IOException e) {
                            try {
                                   c_socket.close();
                            } catch (IOException e1) {
                                   e1.printStackTrace();
                            }
                            e.printStackTrace();
                     }
              }
 
       }
 
       /**测试*/
       public static void main(String[] args) throws Exception {
              Client client = new Client();
              /*初始化客户端*/
              client.initClient();
       }
}


 

基于UDP连接的例子:

1)        UDP接收端

package learn.net;
 
import java.net.DatagramPacket;
import java.net.DatagramSocket;
 
/** UDP接收端*/
public class UdpRecv {
       public static void main(String[] args) throws Exception {
              /* 创建接收端UDP套接字,监听本地地址,端口号9595 */
              DatagramSocket ds = new DatagramSocket(9595);
              byte[] buf = new byte[1024];
              /* 创建一个数据包便于接受 */
              DatagramPacket dp = new DatagramPacket(buf, buf.length);
              /* 通过UDP套接字将数据接收到数据包中 */
              ds.receive(dp);
              /* 获取数据并打印出来 */
              String str = new String(dp.getData(), 0, dp.getLength());
              System.out.println(str);
              /* 获取发送端的地址和端口号信息 */
              System.out.println("IP:" + dp.getAddress().getHostAddress() + ",PORT:"
                            + dp.getPort());
              ds.close();
       }
}


2)        UDP发送端

package learn.net;
 
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
 
/** UDP发送端*/
public class UdpSend {
       public static void main(String[] args) throws Exception {
              /* 创建发送端UDP套接字 */
              DatagramSocket ds = new DatagramSocket();
              String str = "Hello!";
              /*创建一个发送到IP为127.0.0.1,端口号为9595的数据包*/
              DatagramPacket dp= new DatagramPacket(str.getBytes(), str.length(),
                            InetAddress.getByName("127.0.0.1"), 9595);
              /*发送数据包*/
              ds.send(dp);
              /*关闭套接字*/
              ds.close();
       }
}


可以看得出来UDP协议相比TCP协议在使用上还是要简单一点的,当然我们不仅可以使用在两个协议来传输文本数据,传输文件也是没有问题的,这就需要我们灵活运用前面学过的I/O流的知识。


2.   URL类和URLConnection类的使用

1)        URL是UniformResource Locator(统一资源定位符)的简称,比较常见的就是我们经常使用的网址,类似于这样的http://www.google.com/,当然还不止这些,还有例如基于文件传输协议的URL,例如ftp://rtfm.mit.edu/pub/abc.txt。URL的一般形式是:URL 的一般形式是:

<URL的访问方式>://<主机>:<端口>/<路径>

2)        URLConnection可以用来访问网络上的URL资源,URLConnection是所有表示应用程序与URL之间通信连接的类的父类,该类的实例可以用来对由URL引用的资源进行读取和写入操作,就相当于浏览器访网页一样,当然有的时候也会使用它的子类HttpURLConnection,因为HttpURLConnection对http进行了封装。

关于以上两个类,我们举例说明:

 
package learn.net;
 
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
 
public class URLConnectionDemo {
 
       public static void main(String[] args) {
 
              URL url;         
              try {
                     /*创建一个我博客的URL,参数parameter是我加的无效参数*/
                     url = new URL("http://blog.csdn.net/hihiwjc?parameter=xxxxx");                  
                     /*打印此URL的信息*/
                     System.out.println("协议 :"+url.getProtocol());
                     System.out.println("主机名 :"+url.getHost());
                     System.out.println("端口号 :"+url.getPort());
                     System.out.println("路径 :"+url.getPath());
                     System.out.println("文件名 :"+url.getFile());
                     System.out.println("请求参数 :"+url.getQuery());
                     /*使用上面的URL打开到远程主机的连接*/
                     URLConnection conn = url.openConnection();
                     /*设置http头*/
                     conn.addRequestProperty("GET","/  HTTP/1.1");
                     conn.addRequestProperty("Content-Type","application/client");
                     conn.addRequestProperty("Content-Lengt","1000");
                     /*用户代理*/
                     conn.addRequestProperty("User-Agent","Chrome/42.0.2311.152");
                     /*获取到输入流*/
                     InputStream is =conn.getInputStream();
                     /*读取此URL对应的数据,当然这里只是举例,数据肯定不止1KB*/
                     byte[] buff = new byte[1024];
                     int len;
                     len = is.read(buff);
                     /*打印数据*/
                     System.out.println(new String(buff, 0, len));
              } catch (MalformedURLException e) {
                     e.printStackTrace();
              }catch (IOException e) {
                     e.printStackTrace();
              }
       }
}


 

程序输出为:

协议:http
主机名:blog.csdn.net
端口号 :-1
路径:/hihiwjc
文件名:/hihiwjc?parameter=xxxxx
请求参数:parameter=xxxxx
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    
    <htmlxmlns="http://www.w3.org/1999/xhtml">
    


使用URLConnection我们可以方便的访问我们需要的网络资源。

对于Java网络的基础先到这里


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值