Java基础—网络编程

本文介绍了Java中的网络编程基础知识,包括OSI和TCP/IP模型、网络通讯三要素(IP地址、端口、传输协议)以及TCP和UDP的特点和使用。详细讲解了UDP的无连接特性、数据包发送与接收过程,以及TCP的面向连接传输、数据通道建立与关闭。还提到了TCP和UDP在实际应用中的场景,如聊天和图片上传。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、网络模型

OSI模型(七层):物理层、数据链路层、网络层、传输层、会话层、表示层、应用层。
TCP/IP模型(四层):物理层、网际层(IP)、传输层(TCP、UDP协议)、应用层(HTTP、FTP协议)。

二、网络通讯三要素

1、IP地址:网络中设备的唯一标识,java中描述IP的类是:InetAddreess。获取本机的主机:InetAddress i = InetAddress.getLoclHost();获取任一主机:InetAddress i = InetAddress.getByName(“192.168.2.56”);
2、端口:端口是用4为数字表示的。常用的端口:SVN-3690,Tomacat-8080,Apache-80,mySQL-3306。
3、传输协议:常用的是TCP和UDP。

三、TCP、UDP

(一)、UDP
  1、UDP的特点:面向无连接,数据要封包,且不能大于64k,因为无连接,所以不可靠,但是效率快。使用UDP协议传输的应用程序:QQ、桌面共享、网络会议等。
  2、UDP传输:建立发送端、接收端,将数据打包,从发送端用send方法将数据包发送出去,接收端通过reveive方法将数据包接收到已定义好的数据包中,并用数据包的方法解析数据。关闭Socket服务。发送端和接收端是两个独立的运行程序。相关的类:DatagramSocketDatagramPacket
  3、建立UDP发送端服务的步骤:
    (1)、用DatagramSocket建立发送端Socket服务;
    (2)、确定要发送的数据,并用DatagramPacket将数据打包;
    (3)、用DatagramSocket里的send方法将数据包发送出去;
    (4)、关闭Socket服务。
  4、建立UDP接收端服务的步骤:
    (1)、用DatagramSocket建立接收端的Socket服务;
    (2)、用DatagramPacket创建一个数据包;
    (3)、用DatagramSocket中的receive方法接收数据包,并将数据包存放在已定义好的数据包中。
    (4)、用DatagramPacket方法解析数据;
    (5)、关闭接收端Socket服务。
  5、模拟聊天功能

/*
聊天功能模拟。
分析:
     聊天,既能发送信息,也能接收信息,两者同时进行,所以该用两个线程来实现;

步骤:
    1、描述发送端,并实现Runnable接口;
    2、复写run方法。
    3、用Thread建立线程;
    4、将Runnable的子类对象传递给Thread的构造函数;

其他说明:
         接收端没接收端消息,先看看消息是否发送出去了。
*/
import java.net.*;
import java.io.*;
//建立发送端
class ChatSend implements Runnable
{
    private DatagramSocket ds;
    ChatSend(DatagramSocket ds)
    {
        this.ds = ds;
    }
    public void run()
    {
        BufferedReader bufr = null;
        DatagramPacket dp = null;
        try
        {
            //获取键盘录入对象
            bufr = new BufferedReader(new InputStreamReader(System.in));
            String line = null;
            while((line = bufr.readLine()) != null)
            {
                //信息是以字节形式发送,所以需要将字符转字节
                byte[] buf = line.getBytes();
                //将数据打包
                dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.75.1"),8887);
                //将数据包发送出去
                ds.send(dp);
                //判断聊天结束标志
                if(line.equals("goodbye"))
                {
                    //System.out.println(line+"聊天结束!");
                    break;
                }
            }
        }
        catch (IOException e)
        {
            throw new RuntimeException("发送数据失败!");
        }
        finally
        {
            if(bufr != null)
            {
                try
                {
                    bufr.close();
                }
                catch (IOException ie)
                {
                }
            }
        }
    }
}
//建立接收端
class ChatReceive implements Runnable
{
    private DatagramSocket ds;
    ChatReceive(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());
                //判断发送端是否结束聊天
                if(data.equals("goodbye"))
                {
                    System.out.println("发送端结束聊天!");
                    break;
                }
                System.out.println(ip+"---"+data);
            }
        }
        catch (IOException e)
        {
            throw new RuntimeException("数据接收失败!");
        }
    }
}
class ChatTest
{
    public static void main(String[] args) 
    {
        try
        {
            //用Tread建立线程,开启并执行进程
            new Thread(new ChatSend(new DatagramSocket())).start();
            new Thread(new ChatReceive(new DatagramSocket(8887))).start();
        }
        catch (IOException e)
        {
            throw new RuntimeException("建立聊天失败!");
        }

    }
}

(二)、TCP
  1、TCP的特点:面向连接,两者之间建立通讯通道,可在通道中进行大数据传输,安全可靠,但效率稍低。比如:下载。
  2、TCP传输:建立客户端,并与服务器端建立连接,获取客户端的输出流将数据发生到服务器端,服务器端通过获取连接到该服务器上的客户端的读取流,获取客户端发送过来的信息,并用获取到的客户端的输出流将客户端需要的数据反馈给客户端。涉及的类:客户端:Socket,服务器端:ServerSocket。
  3、建立客户端的步骤:
    (1)、通过Socket建立客户端服务,并指定要连接的主机和端口;
    (2)、获取输出流;
    (3)、用输出流将数据传送到服务器;
    (4)、关闭Socket服务;
  4、建立服务器端的步骤:
    (1)、通过ServerSocket建立服务端服务;
    (2)、获取连接到服务器的客户端;
    (3)、通过获取到的客户端的读取流,读取客户端发送过来的信息;
    (4)、关闭Socket服务(可选)。
  5、模拟并发图片上传

/*
客户端并发上传照片。
分析:客户端并发上传照片,要求服务端可以处理多个客户端的请求。

主义事项:客户端端将图片信息发送结束,需要告诉服务端,数据已经发送结束,
           不然服务端在读取数据时读取不到结束标志。
*/
import java.net.*;
import java.io.*;
class TcpPic
{
    public static void main(String[] args)
    {
        Socket s = null;
        FileInputStream ips = null;
        OutputStream out = null;
        InputStream in = null;
        try
        {
            //建立客户端Socket服务,并指定要连接的主机
            s = new Socket("192.168.75.1",10000);
            //指定要上传的图片
            ips = new FileInputStream("ibeacon-01_05.png");
            //获取网络流中的输出流,用于向服务端发送数据
            out = s.getOutputStream();
            byte[] buf = new byte[1024];
            int len = 0;
            //读一次硬盘的图片信息,想服务端发送一次
            while((len = ips.read(buf)) != -1)
            {
                out.write(buf,0,len);
            }
            //告诉服务端已经上传完
            s.shutdownOutput();

            //获取服务端返回的数据
            in = s.getInputStream();
            byte[] bt = new byte[1024];
            int lenth = in.read(bt);
            System.out.println(new String(bt,0,lenth));

            s.close();
        }
        catch (IOException e)
        {
            throw new RuntimeException("数据发送失败!");
        }
        finally
        {
            if(ips != null)
            {
                try
                {
                    ips.close();
                }
                catch (IOException ie)
                {
                }
            }
        }
    }
}
//定义服务端
class ServerPic implements Runnable
{
    private Socket s;
    ServerPic(Socket s)
    {
        this.s = s;
    }
    public void run()
    {
        InputStream in = null;
        FileOutputStream ops = null;
        OutputStream out = null;
        try
        {
            //通过连接到服务端的客户端对象获取输入流
            in = s.getInputStream();
            //获取该客户机的IP
            String path = s.getInetAddress().getHostAddress();
            int count = 0;
            File f = new File(path+"("+count+").png");
            //将文件名封装成File对象,以便判断文件名是否重复
            while(f.exists())
                f = new File(path+"("+(count++)+").png");
            //获取将图片信息写到硬盘的输出流
            ops = new FileOutputStream(f);
            //获取将信息返回给客户端的输出流
            out = s.getOutputStream();
            byte[] buf = new byte[1024];
            int len = 0;
            //一边读取客户端发送过来的数据,一边将数据写到硬盘中
            while((len = in.read(buf)) != -1)
            {
                ops.write(buf,0,len);
            }

            //给客户端返回信息
            out.write("上传成功!".getBytes());
            //System.out.println("商城成功");

            s.close();
        }
        catch (IOException e)
        {
            System.out.println(e.toString());
            throw new RuntimeException("图片接收失败!");
        }
        finally
        {
            if(ops != null)
            {
                try
                {
                    ops.close();
                }
                catch (IOException ie)
                {
                }
            }
        }
    }
}
class TcpPicTest
{
    public static void main(String[] args) 
    {
        ServerSocket ss = null;
        Socket s = null;
        try
        {
            //建立服务端Socket服务
            ss = new ServerSocket(10000);
            //获取连接到该服务端的客户端,并将其封装到一个线程中。
            while(true)
            {
                s = ss.accept();
                //创建线程,开启并执行线程代码
                new Thread(new ServerPic(s)).start();
            }
        }
        catch (IOException e)
        {
            throw new RuntimeException("服务端Socket建立失败!");
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值