美文网首页
Day23--网络编程

Day23--网络编程

作者: pure_joy | 来源:发表于2019-07-25 23:36 被阅读0次
概述
  • 怎么实现两台主机之间的通讯?
    1、找到对方IP。
    2、数据要发送到对方指定的应用程序上。为了标识这些应用程序,所以给这些网络应用程序都用数字进行标识。为了方便称呼这个数字,叫做 端口。逻辑端口。
    3、定义通信规则。这个通信规则称为协议。国际组织定义了通用协议 TCP/IP。
网络模型

OSI参考模型
TCP/IP参考模型


网络模型
IP地址--InetAddress
import java.net.*;

class IpDemo
{
    public static void main(String[] args) throws Exception
    {
        /*InetAddress i = InetAddress.getLocalHost();

        System.out.println(i.toString());
        System.out.println("name:"+i.getHostName());*/

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

        System.out.println(ia.getHostName());
        System.out.println(ia.getHostAddress());
    }
}
TCP和UDP
  • UDP
    1、将数据及源和目的封装成数据包中,不需要建立连接
    2、每个数据报的大小限制在64K内
    3、因无连接,是不可靠协议
    4、不需要建立连接,速度快
  • TCP
    1、建立连接,形成传输数据的通道
    2、在连接中进行大数据量传输
    3、通过三次握手完成连接,是可靠协议
    4、必须建立连接,效率会稍低
Socket
  • Socket就是为网络服务提供的一种机制。
  • 通信的两端都有Socket。
  • 网络通信其实就是Socket间的通信。
  • 数据在两个Socket间通过IO传输。
UDP传输
  • DatagramSocket与DatagramPacket
  • 建立发送端,接收端。
  • 建立数据包。
  • 调用Socket的发送接收方法。
  • 关闭Socket。
    发送端与接收端是两个独立的运行程序。
发送端
import java.net.*;
/*
需求:通过udp传输方式,将一段文字数据发送出去。

思路:
1、建立UDPSocket服务。
2、提供数据,并将数据封装到数据包中。
3、通过socket服务的发送功能,将数据包发出去。
4、关闭资源
*/
class UdpSend
{
    public static void main(String[] args) throws Exception
    {
        //1、创建udp服务,通过DatagramSocket对象。
        DatagramSocket ds = new DatagramSocket();

        //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.8"),10000);

        //3、通过socket服务,将已有数据包发送出去,通过send方法。
        ds.send(dp);

        //4、关闭资源
        ds.close();

    }
}
接收端
/*
需求:
定义一个应用程序,用于接收Udp协议传输的数据并处理。

思路:
1、定义udpsocket服务。通常会监听一个端口,其实就是给这个接收网络应用程序定义数字标识。
    方便于明确哪些数据过来该应用程序可以处理。
2、定义一个数据包,因为要存储接收到的字节数据。
因为数据包对象中有很多功能可以提取字节数据中的不同数据信息。
3、通过socket服务的receive方法将收到的数据存入已定义好的数据包中。
4、通过数据包对象的特有功能,将这些不同的数据取出,打印在控制台上。
5、关闭资源。
*/
class UdpRece
{
    public static void main(String[] args) 
    {
        //1、创建udp、socket,建立端点
        DatagramSocket ds = new DatagramSocket(10000);

        //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();
    }
}
UDP-键盘录入方式数据
import java.net.*;
import java.io.*;
class UdpSend2
{
    public static void main(String[] args) throws Exception
    {
        DatagramSocket ds = new DatagramSocket();

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

        String line = null;

        while((line=bufr.readLine())!=null)
        {
            if("886".equals(line))
                break;

            byte[] buf = line.getBytes();

            DatagramPacket dp =
                    new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.8"),10001);

            ds.send(dp);
        }
        ds.close();
    }
}

class UdpRece2
{
    public static void main(String[] args) throws Exception
    {
        DatagramSocket ds = new DatagramSocket(10001);

        while(true)
        {
            byte[] buf = new byte[1024];
            DatagramPacket dp = new DatagramPacket(buf,buf.length);

            ds.receive(dp);

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

            System.out.println(ip+"::"+data);
        }
    }
}
UDP-聊天
/*
编写一个聊天程序。
有收数据的部分,和发数据的部分。
这两部分需要同时执行。
那就需要用到多线程技术。
一个线程控制收,一个线程控制发。

因为收和发动作是不一致的,所以要定义两个run方法。
而且这两个方法要封装到不同的类中。
*/
import java.io.*;
import java.net.*;
class Send implements Runnable
{
    private DatagramSocket ds;

    Send(DatagramSocket ds)
    {
        this.ds = ds;
    }

    public void run()
    {
        try
        {
            BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));

            String line = null;

            while((line=bufr.readLine())!=null)
            {
                if("886".equals(line))
                    break;

                byte[] buf = line.getBytes();

                DatagramPacket dp =
                        new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.8"),10002);

                ds.send(dp);
            }
        }
        catch(Exception e)
        {
            throw new RuntimeException("发送端失败");
        }
    }
}

class Rece implements Runnable
{
    private DatagramSocket ds;

    Rece(DatagramSocket ds)
    {
        this.ds = ds;
    }

    public void run()
    {
        try
        {
            while(true)
            {
                byte[] buf = new byte[1024];
                DatagramPacket dp = new DatagramPacket(buf,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)
        {
            throw new RuntimeException("接收端失败");
        }
    }
}

class ChatDemo
{
    public static void main(String[] args) throws Exception
    {
        DatagramSocket sendSocket = new DatagramSocket();
        DatagramSocket receSocket = new DatagramSocket(10002);

        new Thread(new Send(sendSocket)).start();
        new Thread(new Rece(receSocket)).start();
    }
}
TCP传输
  • Socket和ServerSocket
  • 建立客户端和服务器端
  • 建立连接后,通过Socket中的IO流进行数据的传输
  • 关闭socket
    同样,客户端与服务器端是两个独立的应用程序。
/*
演示TCP传输

1、TCP分客户端和服务端
2、客戶端对应的对象是Socket
    服务端对应的对象是ServerSocket

*/

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

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

步骤:
1、建立Socket服务,并指定要连接的主机和端口。
*/
import java.net.*;
import java.io.*;
class TcpClient
{
    public static void main(String[] args) throws Exception
    {
        //创建客户端的Socket服务,制定目的主机和端口
        Socket s = new Socket("192.168.1.8",10003); 

        //为了发送数据,应该获取Socket流中的输出流
        OutputStream out = s.getOutputStream();

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

        s.close();
    }
}

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

服务端:
1、建立服务端的socket服务,ServerSocket();
    并监听一个端口。
2、获取连接过来的客户端对象。
    通过ServerSocket的 accept方法。没有连接就会等,所以这个方法阻塞式的。
 3、客户端如果发过来数据,那么服务端要使用对应的客户端对象,并获取到该对象的读取流来读取发过来的数据。
    并打印在控制台。
4、关闭服务端。(可选)
*/
class TcpServer
{
    public static void main(String[] args) 
    {
        //建立服务端Socket服务,并监听一个端口。
        ServerSocket ss = new ServerSocket(10003);

        //通过accept方法获取连接过来的客户端对象。
        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();
    }
}
/*
演示tcp的传输的客户端和服务端的互访

需求:客户端给服务端发送数据,服务端收到后,给客户端反馈信息
*/

/*
客户端:
1、建立socket服务。指定要连接主机和端口。
2、获取socket流中的输出流,将数据写到该流中,通过网络发送给服务端。
3、获取socket流中的输入流,将服务端反馈的数据获取到,并打印。
4、关闭客户端资源。
*/
class TcpClient2
{
    public static void main(String[] args) throws Exception
    {
        Socket s = new Socket("192.168.1.8",10004);

        OutputStream out = s.getOutputStream();

        out.write("服务端,你好".getBytes());

        InputStream in = s.getInputStream();

        byte[] buf = new byte[1024];

        int len = in.read(buf);

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

        s.close();
    }
}

class TcpServer2
{
    public static void main(String[] args) throws Exception
    {
        ServerSocket ss = new ServerSocket(10004);

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

        OutputStream out = s.getOutputStream();

        out.write("哥们收到,你也好".getBytes());

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

    }
}
/*
需求:建立一个文本转换服务器。
客户端给服务端发送文本,服务端会将文本转成大写在返回给客户端。
而且客户端可以不断的进行文本转换。当客户端输入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.8",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)
        {
            bufOut.write(line);
            if("over".equals(line))
                break;

            out.pritnln(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();
    }
}

/*
该例子出现的问题。
现象:客户端和服务端都在莫名的等待。
为什么呢?
因为客户端和服务端都有阻塞式方法。这些方法都没有读到结束标记。那么就一直等
而导致两端,都在等待。 
*/

####### TCP复制文件

import java.io.*;
import java.net.*;
class TextClient
{
    public static void main(String[] args) throws Exception
    {
        Socket s = new Socket("192.168.1.8",10006);

        BufferedReader bufr = 
                new BufferedReader(new FileReader("IPDemo.java"));

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

        DataOutputStream dos = new DataOutputStream(s.getOutputStream());
        long time = System.currentTimeMilllis();

        //out.println(time);
        dos.writeLong(time);

        String line = null;
        while((line=bufr.readLine())!=null)
        {
            out.println(line);
        }

        s.shutdownOutput();//关闭客户端的输出流。相当于给流中加入一个结束标记-1.

        //dos.writeLong(time);

        //out.println("over");

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

        String str = bufIn.readLine();
        System.out.println(str);

        bufr.close();

        s.close();
    }
}

class TextServer
{
    public static void main(String[] args) throws Exception
    {
        ServerSocket ss = new ServerSocket(10006);

        Socket s = ss.accept();
        String ip = s.getInetAddress().getHostAddress();
        System.out.println(ip+"...connected");

        DataInputStream dis = new DataInputStream(s.getInputStream());
        long l = dis.readLong();

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

        PrintWriter out = new PrintWriter(new FielWriter("server.txt"),true);

        String line = null;

        while((line=bufIn.readLine())!=null)
        {
            //if("over".equals(line))
            //  break;
            out.println(line);
        }

        PrintWriter pw = new PrintWriter(s.getOutputStream());
        pw.println("上传成功");

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

相关文章

  • Day23--网络编程

    概述 怎么实现两台主机之间的通讯?1、找到对方IP。2、数据要发送到对方指定的应用程序上。为了标识这些应用程序,所...

  • Android 网络编程 目录

    Android 网络编程 目录 Android 网络编程1 Http协议Android 网络编程2 Okhttp缓...

  • Linux网络编程篇之ICMP协议分析及ping程序实现

    Linux网络编程系列: Linux网络编程篇之Socket编程预备知识 Linux网络编程篇之TCP协议分析及聊...

  • iOS关于HTTP协议和网络编程

    1.网络编程 1>什么是网络编程? 网络编程,是我们iOS程序开发者针对网络模块进行得代码编程,是作为一个资深开发...

  • 网络编程

    网络编程 网络编程: 网络编程主要用于解决计算机与计算机(手机、平板..)之间的数据传输问题。 网络编程: 不需要...

  • 网络基本了解

    网络基础 问题:为什么要学习网络编程?(1)网络编程是一种实时更新应用数据的常用手段(2)网络编程是开发优秀网络应...

  • Android应用开发:网络编程2

    网络编程 Java基础:网络编程 Uri、URL、UriMatcher、ContentUris详解 Android...

  • Http协议

    网络编程 Java基础:网络编程 Uri、URL、UriMatcher、ContentUris详解 Android...

  • 网络编程,TCP,UDP

    day26笔记【网络编程,TCP,UDP】 day26授课目录: 1_网络编程(网络编程概述)(了解) A:计算机...

  • P8架构师告诉你身为程序员必备的技能之一TCP/IP网络编程

    网络编程:操作系统+系统编程知识+TCP/IP网络数据传输协议大部分软件是基于网络环境开发的,因此,网络编程成为程...

网友评论

      本文标题:Day23--网络编程

      本文链接:https://www.haomeiwen.com/subject/fhohrctx.html