JAVA基础 day25 网络编程 IP类 UDP,TCP传输学习 简易聊天工具 TCP并发学习

网络编程

网络通讯要素:

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

端口(0-65535)
传输协议(常用的有TCP/IP,UDP)

网络模型:

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

学习javase主要是在传输层和网际层进行学习。
这里写图片描述

IP类

InetAddress,没有构造方法。

import java.net.*;
class IPDemo
{
    public static void main(String[]args)throws UnknownHostException
    {
        //InetAddress i=InetAddress.getLocalHost();//返回本地主机
        //System.out.println(i);
        //System.out.println(i.getHostAddress()+"---"+i.getHostName());

        InetAddress ia=InetAddress.getByName("www.baidu.com");//给定主机名返回IP地址
        System.out.println(ia);
    }
}

传输协议的区别:

UDP,不需要建立连接,直接发送就行。没接收到就丢包。QQ和视频会议之类都可以用UDP。
TCP:必须建立连接。不能丢包,例子:下载工具使用TC。P
这里写图片描述

socket传输
这里写图片描述

UDP传输协议

UDP创建发送端的步骤
1.通过DatagramSocket创建udp服务
2.通过DatagramPacket封装要发送的数据包
3.通过DatagramSocket的send方法发送数据包
4..关闭资源。

import java.net.*;
class UdpSendDemo
{
    public static void main(String[]args)throws Exception
    {
        DatagramSocket ds=new DatagramSocket();//创建udp服务
        byte[] buf="Udp send test.".getBytes();
        DatagramPacket dp=new DatagramPacket(buf,buf.length,InetAddress.getLocalHost(),10000);//将数据包封装
        ds.send(dp);//发送
        ds.close();//关闭资源
    }
}

UDP创建接收端
1.通过DatagramSocket创建udp服务,并且指定接收哪个端口的信息
2.通过DatagramPacket定义好一个数据包,接受数据。
3.通过DatagramSocket的receive方法接收数据包
4.通过DatagramPacket的方法将数据包中的内容提取出来。

import java.net.*;
class UdpReceiveDemo
{
    public static void main(String[]args)throws Exception
    {
        DatagramSocket ds=new DatagramSocket(10000);//监控10000端口的信息
        byte[]buf=new byte[1024];
        DatagramPacket dp=new DatagramPacket(buf,buf.length);
        ds.receive(dp);
        String s=new String(dp.getData(),0,dp.getLength());
        System.out.println(s);

    }
}

编程,编写简易的聊天工具
1.接收和发送是同时的,所以需要用到多线程

import java.io.*;
import java.net.*;
class Send implements Runnable//发送线程
{
    private DatagramSocket ds;
    Send(DatagramSocket ds)
    {
        this.ds=ds;
    }
    public void run()
    {
        try{
            BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
            String line=null;
            while (!(line=br.readLine()).equals("over"))
            {
                byte[]buf=line.getBytes();
                DatagramPacket dp=new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.199.112"),10008);
                ds.send(dp);
            }
            ds.close();
        }
        catch(Exception e)
        {

            throw new RuntimeException("发送失败");
        }
    }
}
class Receive implements Runnable//接收线程
{
    private DatagramSocket ds;
    Receive(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(10008);
        new Thread(new Send(sendSocket)).start();
        new Thread(new Receive(receSocket)).start();
    }
}

TCP传输

这里写图片描述
Socket实现客户端套接字,ServerSocket实现服务端套接字。
当客户端和服务端连接时,就已经存在一个流。客户端通过这个流传送数据,
而服务端可以通过方法获得客户端的对象,来和客户端进行通讯。

编程:TCP传输

客户端

import java.io.*;
import java.net.*;
class TcpClient
{
    public static void main(String[]args)throws Exception
    {
        Socket s=new Socket("192.168.199.112",11000);//创建服务
        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();

    }
}

服务端

import java.io.*;
import java.net.*;
class TcpServer
{
    public static void main(String[]args)throws Exception
    {
        ServerSocket ss=new ServerSocket(11000);//创建服务端服务
        Socket s=ss.accept();//获取客户端对象
        String ip=s.getInetAddress().getHostAddress();
        System.out.println(ip+"正在连接");
        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();
    }
}

编程:客户端输入数据,服务端将其变成大写后返回

客户端

import java.io.*;
import java.net.*;
class TextCastClient//客户端
{
    public static void main(String[]args)throws Exception
    {
        Socket s=new Socket("192.168.199.112",30000);
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        OutputStream out=s.getOutputStream();
        InputStream in=s.getInputStream();
        byte[]buf=new byte[1024];
        int num=0;
        String line=null;
        while(!(line=br.readLine()).equals("over"))
        {
            out.write(line.getBytes());
            num=in.read(buf);
            String str=new String(buf,0,num);
            System.out.println("客户端收到"+str);
        }
        s.close();
        br.close(); 
    }
}

服务端

import java.io.*;
import java.net.*;
class TextCastServer//服务端
{
    public static void main(String[]args)throws Exception
    {
        ServerSocket ss=new ServerSocket(30000);
        Socket s=ss.accept();
        InputStream in=s.getInputStream();
        OutputStream out=s.getOutputStream();
        byte[]buf=new byte[1024];
        int num=0;
        while (true)
        {
            num=in.read(buf);
            String str=new String(buf,0,num);
            System.out.println("服务端收到"+str);
            String str1=str.toUpperCase();
            out.write(str1.getBytes());
        }

    }
}

编程:TCP上传图片

import java.io.*;
import java.net.*;
class TcpPicCopyClient
{
    public static void main(String[]args)throws Exception
    {
        Socket s=new Socket("192.168.199.112",20005);
        FileInputStream f=new FileInputStream("basketball.jpeg");
        OutputStream out=s.getOutputStream();
        byte[]buf=new byte[1024];
        int num=0;
        while ((num=f.read(buf))!=-1)
        {
            out.write(buf);
        }
        s.shutdownOutput();
        InputStream in=s.getInputStream();
        byte[]buf1=new byte[100];
        int num1=in.read(buf1);
        System.out.println(new String(buf1,0,num1));
    }
}


//服务端
class TcpPicCopyServer
{
    public static void main(String[]args)throws Exception
    {
        ServerSocket ss=new ServerSocket(20005);
        Socket s=ss.accept();
        InputStream in=s.getInputStream();
        OutputStream out=s.getOutputStream();
        FileOutputStream f=new FileOutputStream("1.jpeg");
        byte[]buf=new byte[1024];
        int num=0;
        while ((num=in.read(buf))!=-1)
        {
            f.write(buf);
        }
        out.write("上传成功".getBytes());
        s.close();
        ss.close();

    }
}

在实际运行中,当两个客户端同时连接服务端时,获得一个对象,第一个客户端没运行完,第二个客户端是获取不到对象的,所以需要开启多线程。

编程:Tcp并发上传图片

//客户端
import java.io.*;
import java.net.*;
class PicClient
{
    public static void main(String[]args)throws Exception
    {
        File file=new File(args[0]);
        Socket s=new Socket("192.168.199.112",20010);
        FileInputStream fis=new FileInputStream(file);
        OutputStream out=s.getOutputStream();
        InputStream in=s.getInputStream();
        byte[]buf=new byte[1024];
        int num=0;
        while((num=fis.read(buf))!=-1)
        {
            out.write(buf,0,num);
        }
        s.shutdownOutput();
        byte[]buf1=new byte[1024];
        int num1=in.read(buf1);
        System.out.println(new String(buf1,0,num1));
        fis.close();
        s.close();
    }
}


//服务端,要并发上传
class PicThread implements Runnable
{
    private Socket s;
    PicThread(Socket s)
    {
        this.s=s;
    }
    public void run()
    {
        int count=1;
        String ip=s.getInetAddress().getHostAddress();
        try{
        System.out.println(ip+"--正在连接");
        File file=new File(ip+".jpeg");//当文件存在时,用原文件名+(数字)进行创建,不覆盖
        while(file.exists())
            file=new File(ip+"("+(count++)+")"+".jpeg");
        FileOutputStream fos=new FileOutputStream(file);
        InputStream in=s.getInputStream();
        OutputStream out=s.getOutputStream();
        byte[]buf=new byte[1024];
        int num;
        while((num=in.read(buf))!=-1)
        {
            fos.write(buf,0,num);
        }
        out.write("上传成功".getBytes());
        fos.close();
        s.close();
        }
        catch(Exception e)
        {
            System.out.println("上传失败");
        }

    }
}
class PicServer
{
    public static void main(String[]args)throws Exception
    {
        ServerSocket ss=new ServerSocket(20010);
        while(true)
        {
        Socket s=ss.accept();
        new Thread(new PicThread(s)).start();
        }

    }

}

编程:TCP并发登陆
只能登陆三次,登陆成功客户端显示 欢迎光临,失败显示用户不存在。
登陆成功服务端显示已登陆,失败显示尝试登陆。

import java.io.*;
import java.net.*;
class LoginClient//客户端
{
    public static void main(String[]args)throws Exception
    {
        Socket s=new Socket("192.168.199.112",25000);
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));//读取键盘输入
        PrintStream ps=new PrintStream(s.getOutputStream(),true);
        BufferedReader br1=new BufferedReader(new InputStreamReader(s.getInputStream()));
        for(int x=0;x<3;x++)
        {
            String line=br.readLine();//读取键盘
            if(line==null)
                break;
            ps.println(line);//发送到服务端
            String info=br1.readLine();//接收反馈
            System.out.println(info);
            if(info.contains("欢迎"))//如果登陆成功,就不再循环
                break;
        }
        br.close();
        s.close();
    }
}



//服务端
class LoginThread implements Runnable
{
    private Socket s;
    LoginThread(Socket s)
    {
        this.s=s;
    }
    public void run()
    {
        try{

         for (int x=0;x<3;x++)
         {
            BufferedReader br=new BufferedReader(new InputStreamReader(s.getInputStream()));
            BufferedReader br1=new BufferedReader(new FileReader("user.txt"));
            PrintStream out=new PrintStream(s.getOutputStream());//获取客户端发送的数据
            String name=br.readLine();
            if(name==null)
                break;
            String line=null;
            boolean flag=false;
            while((line=br1.readLine())!=null)//读取的数据和文件里数据对比
            {
                if(name.equals(line))
                {
                    flag=true;
                    break;
                }
            }
            if (flag)
            {
                System.out.println(name+"已登陆");
                out.println((name+"欢迎光临"));
                break;
            }
            else
            {
                System.out.println(name+"尝试登陆");
                out.println((name+"用户名不存在"));
            }   
          }

          s.close();
         }
        catch(Exception e)
        {
            throw new RuntimeException("错误");
        }

    }
}
class LoginServer
{
    public static void main(String[]args)throws Exception
    {
        ServerSocket ss=new ServerSocket(25000);
        while(true)
        {
        Socket s=ss.accept();
        new Thread(new LoginThread(s)
        ).start();
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值