网络编程

来源:互联网 发布:自动打广告软件 编辑:程序博客网 时间:2024/05/06 13:25

第十章 网络编程


1,  IP
a)  本地地址
b)  本地主机名
2,  端口号
a) 用于标识进程的逻辑地址,不同进程的标识
b)有效端口:0 ~ 65535 ,其中0 ~ 1024系统保留或保留端口
3,  传输协议:TCP,UDP
---------------------------------------------------------------------
InetAddress 类  (java.net包)
没有都造函数,所以不能够创建对象,所以必有方法返回该类对象
1,  常见方法
static InetAddress  getLocalHost()\\返回本地主机
static InetAddress  getByName(String host) \\在给定主机名的情况下确定主机的 IP 地址。
static InetAddress[] getAllByName(String host)\\  在给定主机名的情况下,根据系统上配置的名称服务返回其 IP 地址所组成的数组。
static InetAddress  getByAddress(String host, byte[] addr)\\ 根据提供的主机名和 IP 地址创建 InetAddress。
static InetAddress  getByAddress(byte[] addr)\\在给定原始 IP 地址的情况下,返回 InetAddress 对象。
byte[]  getAddress()\\返回此 InetAddress 对象的原始 IP 地址。
String  getHostAddress()\\ 返回 IP 地址字符串(以文本表现形式)。
String  getHostName()\\获取此 IP 地址的主机名。

---------------------------------------------------------------------
UDP传输
1,面向无连接
每个数据报大小,在限制在64字节内
不可靠协议
2,数据包通讯端 DatagramSocket
数据包 Datagrampacket
常见方法:
              DatagramSocket
              构造方法

    DatagramSocket()\\若不指定本端口号,系统会自动分配

    DatagramSocket(int port)

    DatagramSocket(int port, InetAddress laddr)

    DatagramSocket(SocketAddress bindaddr)

connect(InetAddress address, int port)

disconnect()\\  断开套接字的连接。

InetAddress  getInetAddress()\\返回此套接字连接的地址。

          int   getPort()\\返回此套接字的端口。

                     receive(DatagramPacket p)\\ 从此套接字接收数据报包。       de>de>


send(DatagramPacket p)\\ 从此套接字发送数据报包。

close()

       Datagrampacket

       构造方法

DatagramPacket(byte[] buf, int length, InetAddress address, int port)


DatagramPacket(byte[] buf, int length, SocketAddress address)

InetAddress  getInetAddress()\\返回某台机器的 IP 地址,此数据报将要发往该机器或者是从该机器接收到的。

int   getPort()\\返回某台远程主机的端口号,此数据报将要发往该主机或者是从该主机接收到的。

SocketAddress getSocketAddress()\\获取要将此包发送到的或发出此数据报的远程主机的(通常为 IP 地址 + 端口号)。


Int de> de>getLength()\\返回将要发送或接收到的数据的长度。

byte[]  getData()\\返回数据缓冲区。

       setPort(int iport)


       setSocketAddress(SocketAddress address)


       setAddress(InetAddress iaddr)

                     … API

3,    实例


import java.net.*;

/*

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

定义一个udp发送端。

思路:

1,建立updsocket服务。

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

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

4,关闭资源。

*/

class  UdpSend

{

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

    {

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


           DatagramSocket ds = new DatagramSocket(8888);

           //2,确定数据,并封装成数据包。DatagramPacket(byte[] buf, int length, InetAddress address, int port)

           byte[] buf = "udp ge men lai le ".getBytes();

           DatagramPacket dp =

                  new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.254"),10000);

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

           ds.send(dp);

           //4,关闭资源。

           ds.close();
    }


}

/*

需求:

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

定义udp的接收端。

思路:

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

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

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

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

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

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

5,关闭资源。

*/

class  UdpRece

{

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

    {

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

           DatagramSocket ds = new DatagramSocket(10000);

           while(true)\\循环接收数据

           {

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

           byte[] buf = new byte[1024];

           DatagramPacket dp = new DatagramPacket(buf,buf.length);
        //3,通过服务的receive方法将收到数据存入数据包中。

           ds.receive(dp);//阻塞式方法。接收数据报

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

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

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

           int port = dp.getPort(); \\取的发送端的端口号

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

           }


           //5,关闭资源

           //ds.close();

    }


}

---------------------------------------------------------------------

TCP传输

1,   面向无连接,不可靠协议

      分客户端和服务端。客户端对应的对象是Socket。服务端对应的对象是ServerSocket。

2,  客户端Socket

服务端ServerSocket

       常见方法:

              Socket

              构造函数

                     Socket()

                     Socket(InetAddress address, int port)

                     Socket(String host, int port)

InputStream  getInputStream()\\返回此套接字的输入流

OutputStream getOutputStream()\\返回此套接字的输出流

int  getPort()

shutdownOutput()\\禁用此套接字的输出流。

shutdownInput()

boolean isInputShutdown()\\返回是否关闭套接字连接的半读状态

boolean isOutputShutdown()\\返回是否关闭套接字连接的半写状态            
           connect(SocketAddress endpoint)\\  将此套接字连接到服务器。

connect(SocketAddress endpoint, int timeout)\\将此套接字连接到服务器,并指定一个超时值。
      
           close()

ServerSocket

 构造函数

ServerSocket(int port)

ServerSocket()
         
Socket  accept()\\侦听并接受到此套接字的连接。
            
 close()


3,  实例

  /*

客户端,

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

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

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

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

步骤:

1,创建Socket服务。并指定要连接的主机和端口。

*/

import java.io.*;

import java.net.*;

class  TcpClient

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

       {

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

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

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


              OutputStream out = s.getOutputStream();

              out.write("tcp ge men lai le ".getBytes());

              s.close();

       }

}

/*

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

服务端:

1,建立服务端的socket服务。ServerSocket();

       并监听一个端口。


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


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


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


       并打印在控制台。


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

class  TcpServer


{


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


       {

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


              ServerSocket ss = new ServerSocket(10003);


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


              while(true)


              {


              Socket s = ss.accept();


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


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


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


              InputStream in = s.getInputStream();
         
              byte[] buf = new byte[1024];


              int len = in.read(buf);\\阻塞语句


              System.out.println(new String(buf,0,len));


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

              }

              //ss.close();

       }

}


4,  问题
/*
需求:建立一个文本转换服务器。


客户端给服务端发送文本,服务单会将文本转成大写在返回给客户端。


而且客户度可以不断的进行文本转换。当客户端输入over时,转换结束。

分析:

客户端:


既然是操作设备上的数据,那么就可以使用io技术,并按照io的操作规律来思考。


源:键盘录入。


目的:网络设备,网络输出流。


而且操作的是文本数据。可以选择字符流。


步骤


1,建立服务。


2,获取键盘录入。


3,将数据发给服务端。


4,后去服务端返回的大写数据。


5,结束,关资源。


都是文本数据,可以使用字符流进行操作,同时提高效率,加入缓冲。


*/


import java.io.*;

import java.net.*;

class  TransClient


{

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


       {


              Socket s = new Socket("192.168.1.254",10005);


              //定义读取键盘数据的流对象。


              BufferedReader bufr =


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


              //定义目的,将数据写入到socket输出流。发给服务端。


              //BufferedWriter bufOut =


                     //new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));


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


              //定义一个socket读取流,读取服务端返回的大写信息。


              BufferedReader bufIn =


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

              String line = null;

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

              {


                     if("over".equals(line))

                            break;
                  
                     out.println(line);


//                   bufOut.write(line);

//                   bufOut.newLine();

//                   bufOut.flush();

                     String str =bufIn.readLine();

                     System.out.println("server:"+str);               
              }


              bufr.close();


              s.close();


       }


}

/*

服务端:


源:socket读取流。


目的:socket输出流。


都是文本,装饰。
*/
class  TransServer


{

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


       {


              ServerSocket ss = new ServerSocket(10005);


              Socket s = ss.accept();

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

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

              //读取socket读取流中的数据。


              BufferedReader bufIn =


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


 
              //目的。socket输出流。将大写数据写入到socket输出流,并发送给客户端。


              //BufferedWriter bufOut =


                     //new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));


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


              String line = null;


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


                     System.out.println(line);


                     out.println(line.toUpperCase());


//                   bufOut.write(line.toUpperCase());


//                   bufOut.newLine();


//                   bufOut.flush();

              }
              s.close();
              ss.close();
       }


}


/*


该例子出现的问题。


现象:客户端和服务端都在莫名的等待。为什么?

因为客户端和服务端都有阻塞式方法。这些方法么没有读到结束标记。那么就一直等

而导致两端,都在等待。

解决方法:发送端结束发送数据 可调用shutdownOutput()关闭客户端的输出输出流,使得服务端的read()方法跳出阻塞

*/


0 0