黑马程序_网络编程

来源:互联网 发布:免税店mac多少钱 编辑:程序博客网 时间:2024/05/16 15:34

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

 

网络通信三大要素

IP地址端口号传输协议

先说一下网络通信三大要素的概念:

1.IP地址:你要发送数据到指定的位子首先你要找到对方的位子,也就是对 方在网络上的IP地址,IP地址就相当于对方机器的名字,每一台连接网络   的机器都有自己一个与别人不同的IP地址。

2.端口号:数据要发送到对方指定的程序上,因为不同的应用能接收的数据 是不同的,只有相同的应用才能看的懂你发过来的数据,电脑为了区分这些      应用程序。所以要给这些应用程序用数据进行一个标识,用来区分不同的应  用程序。我们一般把这些程序称之为端口。

每一个网络应用程序都会有一个不同的端口也是必须有的(端口号只能是0     65535 并且01024是给系统保留的)

3.传输协议:两个网络应用程序要进行通讯的话,还需要定义一个通讯的规 则,我们把这个规则称为协议。之所以一个应用程序可以使很多人进行通讯,  就是因为他们使用了同一个通信协议。目前用的最多的就是TCP/IP,这是以     个国际组织定义的通用协议,又能在局域网使用,也可以再广域网使用。这是一个非常强大的协议。并且它是默认的广域网协议。      

网络模型

OSI参考模型

TCP/IP参考模型

Java中的IP对象

import java.net.*;

class IPDemo

{

      publicstatic void main(String[] args)throws Exception

      {

             //通过名称来获取一个IP对象

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

             System.out.println(ia.getHostAddress());//获取主机地址

             System.out.println(ia.getHostName());//获取主机名

      }

}

目前网络上最常见用的最多的2种协议是TCP和UDP2种  

TCP的特点:

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

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

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

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

UDP的特点 

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

                    每个数据大小限制在64K

                    因无连接,是不可靠协议

                    不需要建立连接,速度快

Socket(套接字)

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

2.通信的两端都有Socket

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

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

Udp发送端

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

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

DatagramSocket对象封装了udp传输协议的socket对象

DatagramPacket通过这个对象的方法,就可以获取到数据包中的各种信息

需求:通过udp传输方式,将一段文字数据发送出去

1,建立updsocket服务。

2,提供数据,并将数据封装到数据包中。

3,通过socket服务的发送功能,将数据包发出去。

4,关闭资源。

import java.net.DatagramPacket;

import java.net.DatagramSocket;

class Udpsend

{

      publicstatic void main(String[] args)throws Exception

      {

             DatagramSocketds=new DatagramSocket(8888);

             byte[]buf="Udp lai le".getBytes();

              DatagramPacket dp=newDatagramPacket(buf,buf.length,InetAddress.getByName("127.0.0.1"),1000);

             ds.send(dp);

             ds.close();

      }

}

Udp接收端

需求:

定义一个应用程序,用于接收udp协议传输的数据并处理的。

1,定义udpsocket服务。通常会监听一个端口。其实就是给这个接收网络      应用程序定义数字标识。方便于明确哪些数据过来该应用程序可以处理。

2,定义一个数据包,因为要存储接收到的字节数据。

因为数据包对象中有更多功能可以提取字节数据中的不同数据信息。

3,通过socket服务的receive方法将收到的数据存入已定义好的数据包中。

4,通过数据包对象的特有功能。将这些不同的数据取出。打印在控制台上。

5,关闭资源。

import java.net.DatagramPacket;

import java.net.DatagramSocket;

class UdpRece

{

      publicstatic void main(String[] args) throws Exception

      {

             //1,创建udp socket,建立端点。

             DatagramSocketds = new DatagramSocket(10000);//指定监听窗口

             while(true)

             {

             //2,定义数据包。用于存储数据。

             byte[]buf = new byte[1024];

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

             //3,通过服务的receive方法将收到数据存入数据包中。

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

             //4,通过数据包的方法获取其中的数据,比如ip、端口、数据等

             Stringip = dp.getAddress().getHostAddress();//获取字符串ip

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

             intport = dp.getPort();//获取端口

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

             }

             //5,关闭资源

             ds.close();

      }

}

练习一

需求:通过键盘录入,获取要发送的信息

 

import java.net.*;

import java.io.*;

class Udpsend2

{

      publicstatic void main(String[] args)throws Exception

      {

             DatagramSocketds=new DatagramSocket();

             BufferedReaderbufr=new BufferedReader(new InputStreamReader(System.in));

             Stringline=null;

             while((line=bufr.readLine())!=null)

             {

                    if("886".equals(line))

                           break;

                    byte[]buf=line.getBytes();

                    DatagramPacketdp=new DatagramPacket(buf,buf.length,InetAddress.getByName("127.0.0.1"),10001);

                    ds.send(dp);

             }

             ds.close();

      }

}

class Udprece2

{

      publicstatic void main(String[] args)throws Exception

      {

             DatagramSocketds=new DatagramSocket(10001);

             while(true)

             {

                    byte[]buf=new byte[1024];

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

                    ds.receive(dp);

                    Stringip=dp.getAddress().getHostAddress();

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

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

             }

      }

}

练习二

需求:编写一个聊天程序

import java.io.*;

import java.net.*;

class Send implements Runnable

{

      privateDatagramSocket ds;

      publicSend(DatagramSocket ds)

      {

             this.ds= ds;

      }

      publicvoid run()

      {

             try

             {

                    BufferedReaderbufr =

new BufferedReader(newInputStreamReader(System.in));

                    Stringline = null;

                    while((line=bufr.readLine())!=null)

                    {    

                           byte[]buf = line.getBytes();

                           DatagramPacketdp =  newDatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1. 255"),10002);

                           ds.send(dp);

                           if("886".equals(line))

                                  break;

                    }

             }

             catch(Exception e)

             {

                    thrownew RuntimeException("发送端失败");

             }

      }

}

class Rece implements Runnable

{

      privateDatagramSocket ds;

      publicRece(DatagramSocket ds)

      {

             this.ds= ds;

      }

      publicvoid run()

      {

             try

             {

                    while(true)

                    {

                           byte[] buf = new byte[1024];

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

                           ds.receive(dp);

                           Stringip = dp.getAddress().getHostAddress();

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

                           if("886".equals(data))

                           {

                                  System.out.println(ip+"....离开聊天室");

                                  break;

                           }

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

                    }

             }

             catch(Exception e)

             {

                    thrownew RuntimeException("接收端失败");

             }

      }

}

class ChatDemo

{

      publicstatic void main(String[] args) throws Exception

      {

             DatagramSocketsendSocket = new DatagramSocket();

             DatagramSocketreceSocket = new DatagramSocket(10002);

             newThread(new Send(sendSocket)).start();

             newThread(new Rece(receSocket)).start();

      }

}

Tcp传输

SocketServerSocket

建立客户端Socket和服务端ServerSocket

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

关闭Socket

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

Tcp客户端

客户端,

通过查阅socket对象,发现在该对象建立时,就可以去连接指定主机。

因为tcp是面向连接的。所以在建立socket服务时,

就要有服务端存在,并连接成功。形成通路后,在该通道进行数据的传输。

步骤如下:

1.创建客户端的socket服务,指定目的主机和端口

2.为了发送数据,应该获取socket中的输出流

3.然后通过输出流write方法把数据放到socket的输出流里 

4.关闭资源

需求:给服务端发送给一个文本数据。

代码如下:

import java.io.*;

import java.net.*;

class TcpClient

{

      publicstatic void main(String[] args) throws Exception

      {

             //创建客户端的socket服务。指定目的主机和端口

             Sockets = new Socket("192.168.1.254",10003); 

             //为了发送数据,应该获取socket流中的输出流。

             OutputStreamout = s.getOutputStream();

             out.write("您好".getBytes());

             s.close();

      }

}

Tcp服务端

服务端:

1,建立服务端的socket服务。ServerSocket();并监听一个端口。

2,获取连接过来的客户端对象。

通过ServerSokcet accept方法。没有连接就会等,所以这个方法阻塞式的。

3,客户端如果发过来数据,那么服务端要使用对应的客户端对象,并获取  到该客户端对象的读取流来读取发过来的数据,并打印在控制台。

4,关闭服务端。(可选)

步骤如下:

1,建立socket服务指定要连接的主机和端口

2,获取socket流中的输出流 将数据写到该流中通过网络发送给服务端

3,获取socket流中的输入流将服务端反馈的信息获取

4,关闭客户端资源

需求:定义端点接收数据并打印在控制台上。

代码如下:

import java.io.InputStream;

import java.net.ServerSocket;

import java.net.Socket;

class  TcpServer

{

      publicstatic void main(String[] args) throws Exception

      {

             //建立服务端socket服务。并监听一个端口。

             ServerSocketss = new ServerSocket(10003);

             //通过accept方法获取连接过来的客户端对象。

             while(true)

             {

             Sockets = ss.accept();

             Stringip = s.getInetAddress().getHostAddress();

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

             //获取客户端发送过来的数据,那么要使用客户端对象的读取流来读取数据。

             InputStreamin = s.getInputStream();          

             byte[]buf = new byte[1024];

             intlen = in.read(buf);

             System.out.println(newString(buf,0,len));

             s.close();//关闭客户端.

             }

      }

}

 

练习一:

需求:上传图片。

客户端。

1,服务端点。

2,读取客户端已有的图片数据。

3,通过socket输出流将数据发给服务端。

4,读取服务端反馈信息。

5,关闭。

import java.io.*;

import java.net.*;

class SocketPic

{

      publicstatic void main(String[] args) throws Exception

      {

             if(args.length!=1)

             {

                    System.out.println("请选择一个.jpg格式的图片");

                    return;

             }

             Filefile=new File(args[0]);

             if(!(file.exists()&&file.isFile()))

             {

                    System.out.println("该文件有问题,要么不存在。要不有问题");

                    return;

             }

             if(file.getName().endsWith(".jpg"))

             {

                    System.out.println("图片格式不正确");

                    return;

             }

             if(file.length()>1024*5)

             {

                    System.out.println("图片太大");

                    return;

             }

             Sockets=new Socket("127.0.0.1",10007);

             FileInputStreamfis=new FileInputStream(file);

             OutputStreamout=s.getOutputStream();

             byte[]buf=new byte[1024];

             intlen=0;

             while((len=fis.read(buf))!=-1)

             {

                    out.write(buf,0,len);

             }

//告诉服务端数据已写完

             s.shutdownOutput();

             InputStreamin=s.getInputStream();

             byte[]bufin=new byte[1024];

             intnum=in.read(bufin);

             System.out.println(newString(bufin,0,num));

             s.close();

             fis.close();

      }

}

/*服务端可以让多个客户端同时并发访问服务端。那么服务端就将每个客户端封装到一个单独的线程中,这样,就可以同时处理多个客户端请求。

*/

class PicThread implements Runnable

{

      privateSocket s;

      PicThread(Sockets)

      {

             this.s=s;

      }

      publicvoid run()

      {

                    intcount=1;

                    Stringip=s.getInetAddress().getHostAddress();

             try

             {

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

                    InputStreamin=s.getInputStream();

                    Filefile=new File(ip+"("+(count)+")"+".jpg");

                    while(file.exists())

                           file=newFile(ip+"("+(count++)+")"+".jpg");

                    FileOutputStreamfos=new FileOutputStream(file);

                    byte[]buf=new byte[1024];

                    intlen=0;

                    while((len=in.read())!=-1)

                    {

                           fos.write(buf,0,len);

                    }

                    OutputStreamout=s.getOutputStream();

                    out.write("上传成功".getBytes());

                    s.close();             

                    fos.close();

             }

             catch(Exception e)

             {

                    thrownew RuntimeException(ip+"上传失败");

             }

      }

}

class ServerSocketPic

{

      publicstatic void main(String[] args) throws Exception

      {

             ServerSocketss=new ServerSocket(10007);

             while(true)

             {

                    Sockets=ss.accept();

                    newThread(new PicThread(s)).start();

             }

      }

}

URL

URL代表一个统一资源定位符

URL的一些方法:

 StringgetFile()

         获取此 URL的文件名。

 StringgetHost()

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

 StringgetPath()

         获取此 URL的路径部分。

 intgetPort()

         获取此 URL的端口号。

 StringgetProtocol()

         获取此 URL的协议名称。

 StringgetQuery()

         获取此 URL的查询部

如果没有端口getPort()返回-1;系统默认是80

URLConnection conn = url.openConnection();表示到URL所引用的远程对象的连接;

InputStream in = conn.getInputStream();由此可见,URLConnection类把Socket类中的getInputStream()封装起来了;

补充知识点:

InetSocketAddress(IP+端口)

InetAddress(IP)

ServerSocket(int port)

ServerSocket(int port,int backlog);指定队列

域名解析

想要将主机名翻译成ip地址,需要域名解析DNS

可以用映射关系蒙蔽网站。

 

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

 

0 0