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

黑马程序员_【java】网络编程

2014年09月05日 ⁄ 综合 ⁄ 共 10222字 ⁄ 字号 评论关闭

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

网络编程

网络参考模型:OSI参考模型  TCP/IP参考模型

 

网络通讯要素:

IP地址:网络中设备的标识,不易记忆,可用主机名;本地回环地址:127.0.0.1,主机名:localhost

端口号:用于标识进程的逻辑地址,不同进程的标识;有效端口0-65535,其中0-1024被系统使用或是保留端口。

传输协议:即通讯的规则,常见协议有:TCP UDP

TCPUDP的区别:

UDP(聊天软件,视频会议,桌面共享等常用,如QQ

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

2.每个数据包的大小限制在64k

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

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

TCP(下载软件常用,如迅雷)

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

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

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

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

UDP传输

Socket

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

2.通信的两端都有Socket

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

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

获取IP地址代码示例:

import java.net.*;

class IPDemo

{

         publicstatic void main(String[] args)throws UnknownHostException

         {

                   //返回本地主机

                   InetAddress id = InetAddress.getLocalHost();

                   //获取主机名

                   Stringname = id.getHostName();

                   //获取IP地址

                   Stringaddr = id.getHostAddress();

                   System.out.println("name:"+name+",address:"+addr);

                   //通过主机名获取IP地址,这种方法很常用

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

                   Stringname1 = i.getHostName();

                   Stringaddr1 = i.getHostAddress();

                   System.out.println("name:"+name1+",address:"+addr1);

                   //一个主机名可能对应多个IP地址,所以用此方法可以遍历出所有IP地址。

                   InetAddress[]ias = InetAddress.getAllByName("www.baidu.com");                                 for(InetAddress ia : ias)

                   {

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

                   }

         }

}

 

网络通讯过程:

1.找到对方IP

2.数据要发送到对方指定的应用程序上,为了标识这些应用程序,所以给这些网络应用程序都用数字进行标识,为了方便称呼这个数字,叫做端口

3.定义通信规则,这个通讯规则称为协议,国际组织定义了通用协议TCP/IP

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

思路:

1.建立udpsocket服务

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

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

4.关闭资源

示例代码:

import java.net.*;

import java.io.*;

class UdpSend

{

         publicstatic void main(String[] args) throws Exception

         {

                   //1.创建udp服务,通过DatagramSocket对象

                   DatagramSocketds = new DatagramSocket(8888);//8888为发送端的端口号

                   //2.确定数据,并封装成数据包

                   byte[]buf = "hello world".getBytes();

                   DatagramPacketdp =

                            newDatagramPacket(buf,buf.length,InetAddress.getByName("localhost"),10000);

                   //3.通过socket服务,将已有的数据包发送出去,通过send方法。

                   ds.send(dp);

                   }

                   //4.关闭资源

                   ds.close();

         }

}

需求:定义一个应用程序,用于接收udp协议传输的数据并处理,即定义udp的接收端

思路:

1.定义udpsocket服务,监听一个端口,其实就是给这个接收网络应用程序定义数据标识。

         方便于明确哪些数据过来该应用程序可以处理。

2.定义一个数据包用来存储接收到的字节数据,因为数据包对象中有更多功能可以提取字节数据中的不同数据信息。

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

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

5.关闭资源。

示例代码:

import java.net.*;

import java.io.*;

class UdpRece 

{

         publicstatic void main(String[] args) throws Exception

         {

                   //1.创建upd socket,建立端点,并监听10000端口

                   DatagramSocketds = new DatagramSocket(10000);

                   while(true)

                   {

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

                            byte[]buf = new byte[1024];

                            DatagramPacketdp = 

                                     newDatagramPacket(buf,buf.length);

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

                            ds.receive(dp);

                            //4.通过数据包的方法获取其中的数据。

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

                            Stringname = dp.getAddress().getHostName();

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

 

                            System.out.println("addr:"+addr+"----name:"+name+"----data:"+data);

                   }

                   //5.关闭资源。

                   //ds.close();

         }

}

需求:编写一个聊天程序,有收数据的部分和发数据的部分,这两部分需要同时执行,那就需要用到多线程技术,一个线程控制接收,一个线程控制发送。

因为接收和发送动作是不一致的,所以要定义两个run方法,

而且这两个方法要封装到不同的类中。

示例代码:

import java.io.*;

import java.net.*;

class Send implements Runnable

{

         privateDatagramSocket ds ;

         publicSend(DatagramSocket ds)

         {

                   this.ds= ds;

         }

         publicvoid run()

         {

                   try

                   {

                            BufferedReaderbufr = 

                                     newBufferedReader(new InputStreamReader(System.in));

                            Stringline = null;

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

                            {

                                     if("886".equals(line))

                                               break;

                                     byte[]buf = line.getBytes();

                                     DatagramPacketdp=newDatagramPacket(buf,buf.length,InetAddress.getByName("localhost"),10003);

                                     ds.send(dp);

                            }

                   }

                   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*64];

                                     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);

                            }

                   }

                   catch(Exception e)

                   {

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

                   }        

         }        

}

class ChatDemo 

{

         publicstatic void main(String[] args) throws Exception

         {

                   DatagramSocketsendSocket = new DatagramSocket();

                   DatagramSocketreceSocket = new DatagramSocket(10003);

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

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

         }

}

TCP传输

1.SocketServerSocket

2.建立客户端和服务器端客户端对应的对象是Socket服务端对应的对象是ServerSocket

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

4.关闭Socket

需求:创建TCP客户端,通过查阅Socket对象,发现在该对象建立时,就可以去连接指定的主机,因为tcp是面向连接的,所以在建立socket服务时,就要有服务端存在,并连接成功,形成通路后,在该通道进行数据的传输

示例代码:

import java.io.*;

import java.net.*;

class TcpClient

{

         publicstatic void main(String[] args)throws Exception

         {

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

                   Sockets = new Socket("localhost",10004);

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

                   OutputStreamos = s.getOutputStream();

                   os.write("服务器,我来了".getBytes());

                   //关闭Socket服务

                   s.close();

         }

}

需求:定义TCP服务端,接收数据并打印在控制台上。

示例代码:

import java.io.*;

import java.net.*;

class TcpServer

{

         publicstatic void main(String[] args)throws Exception

         {

                   //建立服务端Socket服务,并监听一个端口

                   ServerSocketss = new ServerSocket(10004);

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

                   Sockets = ss.accept();//accept是一个阻塞式方法

                   //获取客户端的IP地址

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

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

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

                   InputStreamis = s.getInputStream();

                   byte[]buf = new byte[1024];

                   intlen = is.read(buf);

                   Stringdata = new String(buf,0,len);

                   System.out.println(data);

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

                   ss.close();//关闭服务端,这是一个可选操作。

         }

}

需求:上传图片

示例代码:

//客户端

import java.io.*;

import java.net.*;

class UploadPicClient

{

         publicstatic void main(String[] args) throws IOException

         {

                   //1.创建Socket服务端点

                   Sockets = new Socket("localhost",50005);

                   //2.读取客户端已有的图片数据

                   FileInputStreamin = new FileInputStream("c:\\1.png");

                   //3.通过socket输出流将数据发给服务端

                   OutputStreamout = s.getOutputStream();

                   byte[]buf = new byte[1024];

                   intlen = 0 ;

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

                   {

                            out.write(buf,0,len);

                   }

                   //告诉服务器数据写完了。

                   s.shutdownOutput();

                   //4.通过Socket输入流读取服务端反馈的信息

                   InputStreamis = s.getInputStream();

                   byte[]bufIn = new byte[1024];

                   intnum = is.read(bufIn);

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

                   //5.关闭Socket服务

                   s.close();

                   in.close();

         }

}

//服务端

class UploadPicServer

{

         publicstatic void main(String[] args) throws IOException

         {

                   //1.创建Socket服务,并监听50005端口

                   ServerSocketss = new ServerSocket(50005);

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

                   Sockets = ss.accept();

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

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

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

                   InputStreamin = s.getInputStream();

                   //创建一个文件输出流对象,并指定数据存放目的地

                   FileOutputStreamout = new FileOutputStream("d:\\sever.png");

                   byte[]buf = new byte[1024];

                   intlen = 0 ;

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

                   {

                            out.write(buf,0,len);

                   }

                   //通过客户端输出流反馈作息给客户端

                   OutputStreamos = s.getOutputStream();

                   os.write("上传图片成功!!".getBytes());

                   //关闭服务

                   out.close();

                   s.close();

                   ss.close();

         }

}

需求:客户端并发上传图片

示例代码:

//客户端

import java.io.*;

import java.net.*;

class UploadPicClient

{

         publicstatic void main(String[] args) throws IOException

         {

                   //主函数传参数  java UploadPicClient c:\1.png

                   //对不符合要求的进行排除

                   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(".png")))

                   {

                            System.out.println("上传的文件格式不正确,请重新选择!");

                            return;

                   }

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

                   {

                            System.out.println("文件过大,请重新选择!");

                            return;

                   }

                   Sockets = new Socket("localhost",50005);

                   FileInputStreamin = new FileInputStream(file);

                   OutputStreamout = s.getOutputStream();

                   byte[]buf = new byte[1024];

                   intlen = 0 ;

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

                   {

                            out.write(buf,0,len);

                   }

                   s.shutdownOutput();

                   InputStreamis = s.getInputStream();

                   byte[]bufIn = new byte[1024];

                   intnum = is.read(bufIn);

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

                   s.close();

                   in.close();

         }

}

/*服务端

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

如何定义线程呢?

只要明确了每一个客户端要在服务端执行的代码即可,将该代码存入run方法中。

*/

class PicThread implements Runnable

{

         privateSocket s ;

         PicThread(Sockets )

         {

                   this.s= s;

         }

         publicvoid run()

         {

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

                   intnum = 1; 

                   try

                   {

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

                            InputStreamin = s.getInputStream();

                            Filefile = new File("d:\\server.png");

                            while(file.exists())

                                     file= new File("d:\\server("+(num++)+").png");

 

                            FileOutputStreamout = new FileOutputStream(file);

                            byte[]buf = new byte[1024];

                            intlen = 0 ;

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

                            {

                                     out.write(buf,0,len);

                            }

                            OutputStreamos = s.getOutputStream();

                            os.write("上传图片成功!!".getBytes());

                            out.close();

                            s.close();  

                   }

                   catch(Exception e)

                   {

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

                   }

         }

}

class UploadPicServer

{

         publicstatic void main(String[] args) throws IOException

         {

                   ServerSocketss = new ServerSocket(50005);

                   while(true)

                   {

                            Sockets = ss.accept();

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

                   }

         }

}

需求:模拟一个简单的浏览器

示例代码:

import java.io.*;

import java.net.*;

class MyIE

{

         publicstatic void main(String[] args)throw Exception 

         {

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

                   PrintWriterout = new PrintWriter(s.getOutStream(),true);

                   out.println("GETHTTP/1.1");

                   out.println("Accept:*/*");

                   out.println("Accept-Language:zh-cn");

                   out.println("Host:127.0.0.1:14000");

                   out.println("Connection:Keep-Alive");

                   out.println();//一定要打这个空格。

                   BufferedReaderbufr = 

                            newBufferedReader(new InputStreamReader(s.getInputStream()));

                   Stringline = null;

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

                   {

                            System.out.println(line);

                   }

                   s.close();

         }

}

需求:自定义一个服务器

示例代码:

import java.io.*;

import java.net.*;

class ServerDemo

{

         publicstatic void main(String[] args) throws Exception

         {

                   ServerSocketss = new ServerSocket(14000);

                   while(true)

                   {

                            Sockets = ss.accept();

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

                   }

         }

}

class ServerThread implements Runnable

{

         privateSocket s ;

         ServerThread(Sockets)

         {

                   this.s= s;

         }

         publicvoid run()

         {

                   System.out.println(s.getInetAddress().getHostAddress());

                   try

                   {

                            InputStreamin = s.getInputStream();

                            byte[]buf = new byte[1024];

                            intlen = 0;

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

                            {

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

                            }

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

                            out.println("<b>客户端你好");

                            s.close();

                   }

                   catch(Exception e)

                   {

                            thrownew RuntimeException("failed");

                   }

         }

}

 

 

URL

URL代表一个统一资源定位符,它是指向互联网资源的指针。资源可以是简单的文件或目录,也可以是对更为复杂的对象的引用,例如对数据库或搜索引擎的查询。

常用方法:

 Object

getContent()

            获取此 URL 的内容。

 Object

getContent(Class[] classes)

            获取此 URL 的内容。

 int

getDefaultPort()

            获取与此 URL 关联协议的默认端口号。

 String

getFile()

            获取此 URL 的文件名。

 String

getHost()

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

 String

getPath()

            获取此 URL 的路径部分。

 int

getPort()

            获取此 URL 的端口号。

 String

getProtocol()

            获取此 URL 的协议名称。

 String

getQuery()

            获取此 URL 的查询部分。

 

 

URLCollection

它代表应用程序和 URL 之间的通信链接。此类的实例可用于读取和写入此 URL 引用的资源。通常,创建一个到 URL 的连接需要几个步骤:

openConnection()

connect()

对影响到远程资源连接的参数进行操作。

与资源交互;查询头字段和内容。

---------------------------->
时间

  1. 通过在 URL 上调用     openConnection 方法创建连接对象。
  2. 处理设置参数和一般请求属性。
  3. 使用 connect 方法建立到远程对象的实际连接。
  4. 远程对象变为可用。远程对象的头字段和内容变为可访问。

使用以下方法修改设置参数:

  • setAllowUserInteraction
  • setDoInput
  • setDoOutput
  • setIfModifiedSince
  • setUseCaches

使用以下方法修改一般请求属性:

  • setRequestProperty

在建立到远程对象的连接后,以下方法用于访问头字段和内容:

  • getContent
  • getHeaderField
  • getInputStream
  • getOutputStream

某些头字段需要经常访问。以下方法:

  • getContentEncoding
  • getContentLength
  • getContentType
  • getDate
  • getExpiration
  • getLastModifed

 

 

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

抱歉!评论已关闭.