现在的位置: 首页 > 综合 > 正文

黑马程序员—Java编程知识总结网络

2018年05月23日 ⁄ 综合 ⁄ 共 7896字 ⁄ 字号 评论关闭

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


Java编程知识总结—交通灯分析。

  网络编程的本质是两个设备之间的数据交换,当然,在计算机网络中,设备主要指计算机。

数据传递本身没有多大的难度,不就是把一个设备中的数据发送给两外一个设备,然后接受另外一个设备反馈的数据。

现在的网络编程基本上都是基于请求/响应方式的,也就是一个设备发送请求数据给另外一个,然后接收另一个设备的反馈。

在网络编程中,发起连接程序,也就是发送第一次请求的程序,被称作客户端(Client),等待其他程序连接的程序被称作服务器(Server)

客户端程序可以在需要的时候启动,而服务器为了能够时刻相应连接,则需要一直启动。

例如以打电话为例,首先拨号的人类似于客户端,接听电话的人必须保持电话畅通类似于服务器。连接一旦建立以后,就客户端和服务器端就可以进行数据传递了,

而且两者的身份是等价的。在一些程序中,程序既有客户端功能也有服务器端功能,最常见的软件就是BTemule这类软件了。

网络通讯要素:

IP地址

端口号

传输协议

 

IP地址:InetAddress

网络中设备的标识

不易记忆,可用主机名

本地回环地址:127.0.0.1 主机名:localhost

端口号

用于标识进程的逻辑地址,不同进程的标识

有效端口:0~65535,其中0~1024系统使用或保留端口。

备注:不是所谓的物理端口!

传输协议

通讯的规则

常见协议:TCPUDP

TCPUDP的联系和用途

.区别

  二者都是有用的和常用的,如果纯粹从概念上区分二者就比较费解了,我们直接从功能上进行区分,简单明了:

  这两种传输协议也就是合于适配不同的业务和不同的硬件终端。

  在使用中,类似于图像、声音等对可靠性要求没有那么高的业务可以用UDP,他们不需要准确存储对准确性无要求但要求速度快。 

  类似于文本、程序、文件等要求可靠的数据最好就用TCP,但会牺牲一些速度。

  对系统资源的要求:CP较多,UDP少。

  程序结构:UDP程序结构较简单,TCP复杂。

  流模式与数据报模式:TCP保证数据正确性,UDP可能丢包;TCP保证数据顺序,UDP不保证

.用途

  TCP是面向连接的,有比较高的可靠性,一些要求比较高的服务一般使用这个协议,如FTPTelnetSMTPHTTPPOP3等,而
UDP
是面向无连接的,使用这个协议的常见服务有DNSSNMPQQ等。对于QQ必须另外说明一下,QQ2003以前是只使用UDP协议的,其服务器 使用8000端口,侦听是否有信息传来,客户端使用4000端口,向外发送信息(这也就不难理解在一般的显IPQQ版本中显示好友的IP地址信息中端口
常为4000或其后续端口的原因了),即QQ程序既接受服务又提供服务,在以后的QQ版本中也支持使用TCP协议了。

  Udp是一种面向无连接的通信协议,该协议使得数据传输的速度得到大幅度的提高。视频聊天语音聊天基本都是用UPD协议。

总结:

一、UDP:

            1、将数据源和目的地封装到数据包中,不需要建立连接

              2、每个数据包的大小限制在64k以内

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

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

例子:聊天、对讲机就是UDP的,面向无连接(不管在不在,知不知道,只管发送,求速度),丢数据也不管。速度快。数据被分成包

二、TCP:

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

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

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

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

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

InetAddress getByName(Stringhost):在给定主机名的情况下确定主机的ip地址。

InetAddress getLocalHost():返回本地主机。

InetAddress[]getAllByName(String host)

ip.getHostAddress(),

ip.getHostName()

 

Eg

package july76net;

 

import java.net.InetAddress;

 

public class Demo1 {

  public static void main(String[] args) throws Exception {

     

     InetAddress i = InetAddress.getLocalHost();

     System.out.println(i);

     

     i = InetAddress.getByName("www.baidu.com");

     System.out.println(i);

     System.out.println(i.getHostAddress());

     

     System.out.println(i.getHostName());

  }

}

 

输出:

XP-201304252326/10.6.147.2

www.baidu.com/61.135.169.105

61.135.169.105

www.baidu.com

 

Socket

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

通信的两端都有Socket

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

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

UDP传输

 

:只要是网络传输,必须有socket

:数据一定要封装到数据包中,数据包中包括目的地址、端口、数据等信息。

 

直接操作udp不可能,对于java语言应该将udp封装成对象,易于我们的使用,这个对象就是DatagramSocket.封装了udp传输协议的socket对象。

 

因为数据包中包含的信息较多,为了操作这些信息方便,也一样会将其封装成对象。这个数据包对象就是:DatagramPacket.通过这个对象中的方法,就可以获取到数据包中的各种信息。

 

DatagramSocket具备发送和接受功能,在进行udp传输时,需要明确一个是发送端,一个是接收端。

 

udp的发送端:

:建立udpsocket服务,创建对象时如果没有明确端口,系统会自动分配一个未被使用的端口。

:明确要发送的具体数据。

:将数据封装成了数据包。

:用socket服务的send方法将数据包发送出去。

:关闭资源。

 

udp的接收端:

:创建udpsocket服务,必须要明确一个端口,作用在于,只有发送到这个端口的数据才是这个接收端可以处理的数据。

:定义数据包,用于存储接收到数据。

:通过socket服务的接收方法将收到的数据存储到数据包中。

:通过数据包的方法获取数据包中的具体数据内容,比如ip、端口、数据等等。

:关闭资源。

 

 

Eg

发送端(客户端)

import java.net.*;

class UdpSend{

       public static void main(String[]args)throws Exception {

               // 1,建立udpsocket服务。

               DatagramSocket ds = newDatagramSocket(8888);//指定发送端口,这个可以不指定,系统会随机分配。

               // 2,明确要发送的具体数据。

               String text = "udp传输演示 哥们来了";

               byte[] buf = text.getBytes();

               // 3,将数据封装成了数据包。

               DatagramPacket dp = newDatagramPacket(buf,buf.length,InetAddress.getByName("10.1.31.127"),10000);

               // 4,用socket服务的send方法将数据包发送出去。

               ds.send(dp);

               // 5,关闭资源。

               ds.close();

       }

}

 

接收端(服务器端)

 

import java.net.*;

class UdpRece {

       public static void main(String[] args)throws Exception{

               // 1,创建udpsocket服务。

               DatagramSocket ds = newDatagramSocket(10000);//必须指定,并且和上面的端口号一样!

               // 2,定义数据包,用于存储接收到数据。先定义字节数组,数据包会把数据存储到字节数组中。

               byte[] buf = new byte[1024];

               DatagramPacket dp = new DatagramPacket(buf,buf.length);

               // 3,通过socket服务的接收方法将收到的数据存储到数据包中。

               ds.receive(dp);//该方法是阻塞式方法。

               // 4,通过数据包的方法获取数据包中的具体数据内容,比如ip,端口,数据等等。

               String ip =dp.getAddress().getHostAddress();

               int port = dp.getPort();

               String text = newString(dp.getData(),0,dp.getLength());//将字节数组中的有效部分转成字符串。

               System.out.println(ip+":"+port+"--"+text);

               // 5,关闭资源。

               ds.close();

       }

}

 

 

练习:

通过键盘录入获取要发送的信息。

将发送和接收分别封装到两个线程中。

 

package july76net;

//一个聊天的例子,利用UDP传输协议

 

importjava.io.BufferedReader;

import java.io.IOException;

importjava.io.InputStreamReader;

importjava.net.DatagramPacket;

importjava.net.DatagramSocket;

import java.net.InetAddress;

 

//客户端,发送端

class Send implementsRunnable {

  private DatagramSocket ds;

 

  public Send(DatagramSocket ds) {

     super();

     this.ds = ds;

  }

 

  @Override

  public void run() {

     try {

       BufferedReader br = new BufferedReader(new InputStreamReader(

             System.in));//数据源是键盘录入

       String line;

       while ((line = br.readLine()) != null) {

          byte[] buf = line.getBytes();

          DatagramPacket dp = new DatagramPacket(buf, buf.length,

                InetAddress.getByName("localhost"),10225);

 

          ds.send(dp);

       }

     } catch (IOException e) {

       e.printStackTrace();

     }

  }

}

 

//服务器端,接收端

class Rece implementsRunnable {

  private DatagramSocket ds;

 

  public Rece(DatagramSocket ds) {

     super();

     this.ds = ds;

  }

 

  @Override

  public void run() {

     try {

       while (true) {

          byte[] buf = new byte[1024];

 

          DatagramPacket dp = new DatagramPacket(buf, 0,buf.length);

          ds.receive(dp);

 

          String ip = dp.getAddress().getHostAddress();

          String data = new String(dp.getData(), 0, dp.getLength());

 

          System.out.println(ip + "  
  " + data);

       }

     } catch (Exception e) {

       e.printStackTrace();

     }

  }

}

 

public class Demo6 {

  public static void main(String[] args) throws Exception {

     DatagramSocket sendDs = new DatagramSocket();

     DatagramSocket receDs = new DatagramSocket(10225);

     new Thread(new Send(sendDs)).start();

     new Thread(new Rece(receDs)).start();

  }

}

 

输出:

你好

127.0.0.1    你好

你好

你好

 

题目:上传文件,多客户端上传,并且保证不会因为文件的名称而重复!

 

客户端:

package july76net;

 

importjava.io.BufferedReader;

import java.io.FileReader;

import java.io.InputStreamReader;

import java.io.PrintWriter;

import java.net.Socket;

 

public class Demo22 {

  public static void main(String[] args) throws Exception {

     Socket s = new Socket("localhost", 12036);

     

     BufferedReader br = new BufferedReader(new FileReader("E:/你好.txt"));

     PrintWriter pw = new PrintWriter(s.getOutputStream(),true);

     

     BufferedReader br2 = new BufferedReader(newInputStreamReader(s.getInputStream()));

     

     

     String line;

     while((line = br.readLine()) != null){

       pw.println(line);

     }

     s.shutdownOutput();

     

     String str = br2.readLine();

     System.out.println(str);

     s.close();

  }

}

 

服务器端:

package july76net;

 

importjava.io.BufferedReader;

import java.io.File;

import java.io.FileWriter;

importjava.io.InputStreamReader;

import java.io.PrintWriter;

importjava.net.ServerSocket;

import java.net.Socket;

 

 

class MyUpdate implementsRunnable{

  private Socket s;

 

  public MyUpdate(Socket s) {

     super();

     this.s = s;

  }

 

  @Override

  public void run() {

     

     String ip = s.getInetAddress().getHostAddress();

     System.out.println(ip+".........connected!");

     int count = 0;

     try {

       BufferedReader br = new BufferedReader(newInputStreamReader(s.getInputStream()));

       File file = new File("E:/");

       File f = new File(file,"你好"+count+".txt");

       while(f.exists()){//如果写成if,就不可以!

          f = new File(file,"你好"+(++count)+".txt");

       }

       PrintWriter pw = new PrintWriter(new FileWriter(f),true);

       PrintWriter pw2 = new PrintWriter(s.getOutputStream(),true);

       

       String line;

       while((line = br.readLine()) != null){

          pw.println(line);

       }

       

       pw2.println("恭喜您,上传成功!");

       s.close();

     } catch (Exception e) {

       e.printStackTrace();

     }

  }

}

 

public class Demo23 {

  public static void main(String[] args) throws Exception {

     

     ServerSocket ss = new ServerSocket(12036);

     while(true){

       Socket s = ss.accept();

       new Thread(new MyUpdate(s)).start();

     }

  }

}



抱歉!评论已关闭.