java网络编程之UDP、TCP协议

在不同计算机之间进行通信时,需要具备拥有唯一标识的ip地址以及端口号,每个ip地址对应一台主机,每台主机上有65536个端口号,每个端口号能且只能承载一个进程的运行。

要进行网络通信时,就要了解一个新的概念—socket(套接字),用于描述IP地址和端口号,是一个通信链的句柄。应用程序通常使用套接字来向网络发出请求或应答网络请求,也不易实现不同虚拟机或计算机之间的通信。socket的英文含义原指“插座”,所以如果将每一台主机比喻成一个房间,那么socket就是房间里存在的多个插座,每个插座具有不同的编号,并提供不同的电流,这样保证了不同的socket可以对外提供不同的服务。

有了通信的“介质”后,还需要遵循某种协议才能正常进行,这种协议就是基于IP协议的TCP协议和UDP协议。

一、UDP协议(User Datagram Protocol)
1、特点
UDP协议指客户端向服务端发送一个数据包,但对于服务端是否能收到数据不作处理。
(1)将数据即源和目的封装成数据包,不需要建立连接
(2)每个数据报的大小限制在64k
(3)不可靠协议
(4)速度快
2、使用
(1)发送端

 步骤:
     ①建立udp服务
     ②提供数据,并将数据封装到数据包中
     ③通过socket服务的发送功能,将数据包发送出去
     ④关闭资源
package 网络编程;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class UdpSend {

    public static void main(String[] args) throws Exception {
        //创建DatagramSocket对象指定发送端端口号
        DatagramSocket socket = new DatagramSocket(5000);   
        //调用InetAddress类的getByName方法,通过指定主机名来获取接收端IP地址
        InetAddress address = InetAddress.getByName("127.0.0.1"); 
        //指定发送的数据
        String str = "hello world!";
        byte[] buff = str.getBytes();
        //将数据封装到DatagramPacket对象中,并指定接收端的IP地址和端口号,然后发送
        DatagramPacket packet = new DatagramPacket(buff, buff.length,address,8255);
        socket.send(packet);
        if(socket!=null)
            socket.close();
    }
}

(2)接收端:

步骤:
    ①定义udp的socket服务
    ②定义一个数据包,因为要存储接收到的字节数据,可以提取数据中的不同信息
    ③通过socket服务的receive方法收到的数据存到已定义好的数据包中
    ④取数据,然后关闭资源
package 网络编程;

import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class UdpReceive {

    public static void main(String[] args) throws Exception{
        //创建DatagramSocket对象指定接收端端口号
        DatagramSocket socket = new DatagramSocket(8255);
        //将接收的数据存在DatagramPacket对象中
        byte[] buf = new byte[1024];
        DatagramPacket packet = new DatagramPacket(buf,buf.length);
        socket.receive(packet); 
        //使用DatagramPacket中的方法来获取发送端的IP地址和端口号
        String ip = packet.getAddress().getHostAddress();
        int port = packet.getPort();
        String data = new String(packet.getData(), 0, packet.getLength());
        System.out.print("数据是:"+data+"ip是:"+ip+"端口是:"+port);
        socket.close();
    }

}

对上面的程序进行测试,先运行接收端程序,然后运行发送端程序,可以看到数据发送过去并显示发送端信息(ip地址和端口号)

这里写图片描述

二、TCP协议(Transfer Control Protocol(传输控制协议))
1、特点
TCP协议请求网络时会经历“三次握手”,指客户端向服务端发送请求,然后服务端收到请求后回应客户端已收到,最后客户端向服务端发送数据。
(1)建立连接,形成传输数据的通道
(2)在连接中进行大数据量传输
(3)通过三次握手完成连接,可靠协议
(4)必须建立连接,效率会降低

2、使用
(1)客户端

    步骤:
        ①创建socket服务,Socket,连接服务端地址并指定端口
        ②获取写入输出流,并写入数据
package 网络编程;
/*
 * 需求:客户端输入的字符串发送给服务器端,然后将大写格式返回给客户端
 * 
 * TCP客户端,提供输出流
 */
import java.io.BufferedReader;
import java.io.BufferedWriter;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;

public class TcpClient {

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

        //创建客户端Socket指定服务器端主机和端口号
        Socket socket = new Socket("127.0.0.1", 5698);
        //获取键盘输入的数据
        InputStreamReader isr = new InputStreamReader(System.in);
        BufferedReader br = new BufferedReader(isr);
        //获取网络输出流,用于向网络上写数据
        OutputStream os = socket.getOutputStream();
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));
        //获取网络输入流,用于接收网络数据
        InputStream is = socket.getInputStream();
        BufferedReader br1 = new BufferedReader(new InputStreamReader(is));

        /*
         *  下面代码为读取键盘输入数据
         *  并将其写入网络流用于服务器
         *  端的接收,服务器接收到后 
         *
         */
        String line = null;
        while((line = br.readLine())!= null){
            if(line.equals("over"))
                break;
            bw.write(line);
            bw.newLine();
            bw.flush();
            String len = br1.readLine();
            System.out.println(len);
        }
        System.out.println("已收到");
        Thread.sleep(5000);
        br.close();
        socket.close();
    }
}

(2)服务器端

步骤:
    ①建立服务端socket服务,serverSocket,并监听一个 端口
    ②获取连接过来的客户端对象,通过调用accept方法,阻塞式方法
    ③获取一个读取输入流
package 网络编程;
/*
 * TCP服务器端
 * 
 * 
 */

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class TcpServer {

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

        //创建服务器端Socket并指定该服务器端口号
        ServerSocket ss = new ServerSocket(5698);
        //获取客户端Socket对象
        Socket socket = ss.accept();
        //获取网络输入流
        InputStream is = socket.getInputStream();
        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        //获取网络输出流
        OutputStream os = socket.getOutputStream();
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));

        //使用打印流输出
//      PrintStream ps = new PrintStream(os,true);

        //获得客户端发送的数据后并向客户端返回数据
        String line=null;
        while((line = br.readLine())!=null){

//          ps.println(line.toUpperCase());     
            bw.write(line.toUpperCase());
            bw.newLine();
            bw.flush(); 
        }
        System.out.println("已发送");
        ss.close();
    }
}

下面为测试结果:

这里写图片描述

三、使用Socket自定义浏览器向tomcat服务器发送Http请求

“`
package clientandserver;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;

/*
*
* 自定义浏览器
*
*/
public class DesignBrowns {

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

    Socket socket = new Socket("192.168.238.2", 8080);
    PrintStream out = new PrintStream(socket.getOutputStream(),true);
    out.println("GET /myweb/wk.html HTTP/1.1");
    out.println("*/*");
    out.println("Accept-Language: zh-CN");
    out.println("Host: 192.168.238.2:11000");
    out.println("Connection: closed");

    //使用空行将请求头和请求体隔开
    out.println();
    out.println();

    BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    String line = null;
    while((line = br.readLine())!= null){
        System.out.println(line);
    }
    br.close();
    socket.close();


}

}

这里访问服务器的一个html文件,服务器返回响应数据以及文件数据,只是该“浏览器”没有解析html的功能,所以只能原样输出。
“`这里写图片描述
这里写图片描述

四、自定义服务器

package clientandserver;

import java.io.InputStream;
import java.io.PrintStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

/*
 * 
 * 自定义服务端
 * 
 */
public class DesignServer {

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

        ServerSocket ss = new ServerSocket(11000);
        Socket socket = ss.accept();
        String ip = InetAddress.getLocalHost().getHostAddress();

        InputStream is = socket.getInputStream();

        byte[] buf = new byte[1024];
        int len= is.read(buf);
        System.out.println(new String(buf,0,len));

//      BufferedWriter bw = new BufferedWriter(new OutputStreamWriter
//                          (socket.getOutputStream()));

        PrintStream ps = new PrintStream(socket.getOutputStream());
        ps.println("<font size='7' color='red'>这是一个自定义的服务器!</font>");
        ps.close();

//      bw.write("<font size='7' color='red'>nihao</font>");
//      bw.newLine();
        ss.close();
//      bw.close();

    }

}

这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值