Day23-2.UDP编程

1 UDP编程(Socket编程)

  1. 概述:Socket是两台计算机的通信点
  2. 别称:Socket编程也称为套接字编程、通信点编程、端到端编程、点到点编程

2 UDP编程说明

  1. UDP编程的步骤:
    发送端:
          1、准备通信点对象
          2、准备发送的包裹对象
          3、调用通信点的发送方法
          4、关闭通信点
    接收端:
          1、准备通信点对象
          2、准备接收数据的容器
          3、调用通信点的接收方法接收数据
          4、解析并使用接收到的数据
          5、关闭通信点
  2. 使用的Socket是:DatagramSocket
  3. 构造方法:
    DatagramSocket():不指定端口号,创建通信点,端口号随机分配,一般用于发送端
    DatagramSocket(int port):指定端口号,创建通信点,一般用于接收端
  4. 成员方法:
    send(DatagramPacket dp):将一个dp数据报包发送
    receive(DatagramPacket dp):将数据接收到dp参数中
  5. DatagramPacket介绍:
    (1)表示一个数据报数据的封装对象的类型
    (2)构造方法:
    DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port)
    第一个参数:表示需要发送的数据
    第二个参数:表示从数组的哪一个位置开始发送
    第三个参数:发送字节的长度
    第四个参数:发送给哪一个ip
    第五个参数:发送给哪一个端口号
    DatagramPacket(byte[] buf, int length)
  6. 常用成员方法:
函数Value
getData()返回该数据包中的字节数组
getLength()返回该数据包中接收到的字节个数
getAddress()获取发送端的InetAddress对象
getPort()获取发送端的端口号

3 案例1

需求:
(1)发送端实现键盘录入发送数据
(2)发送端可以一直录入数据,直到录入的数据为:end,结束发送
(3)接收端可以一直接收发送端录入的数据

3.1 发送端代码

package udp.demo2;

import java.io.IOException;
import java.net.*;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;

public class Sender {
    public static void main(String[] args) throws IOException {
        //1、先创建一个通信点对象
        DatagramSocket ds = new DatagramSocket();
        //2、键盘录入信息发送
        Scanner sc = new Scanner(System.in);
        while(true){
            System.out.println("请录入您要发送的数据:");
            String str = sc.nextLine();
            //3、将数据封装为一个数据报包
            byte[] bs = str.getBytes();
            DatagramPacket dp = new DatagramPacket(bs,0,bs.length, InetAddress.getByName("192.168.38.226"),10010);
            //4、发送信息
            ds.send(dp);
            if(str.equals("end")){
                break;
            }
        }
        //5、关闭通信点
        ds.close();
    }
}

3.2 接收端代码

package udp.demo2;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

public class Receiver {
    public static void main(String[] args) throws IOException {
        //1、准备一个接收端的通信点对象
        DatagramSocket ds = new DatagramSocket(10010);
        //2、准备一个数据报包,用来接收数据
        byte[] bs = new byte[1024];
        while(true){
            DatagramPacket dp = new DatagramPacket(bs,bs.length);
            //3、使用方法接收获取数据
            ds.receive(dp);
            //4、解析并使用数据报包中的数据
            byte[] bs2 = dp.getData();
            int len = dp.getLength();
            String str = new String(bs2,0,len);
            if(str.equals("end")){
                break;
            }
            System.out.println("接收的数据为:" + str);
        }
        //5、关闭通信点
        ds.close();
    }
}

4 案例2

需求:
(1)实现接收端和发送端可以互相通信
(2)两端都可以使用键盘录入发送数据,录入的结果为end,结束通信

4.1 发送端代码

package udp.demo3;

import java.io.IOException;
import java.net.*;
import java.util.Scanner;

public class Sender {
    public static void main(String[] args) throws IOException {

        DatagramSocket ds = new DatagramSocket();
        Scanner sc = new Scanner(System.in);
        while(true){
            //发送端发送的数据:
            System.out.println("请录入您要发送的数据:");
            String str = sc.nextLine();
            byte[] bs = str.getBytes();
            DatagramPacket dp = new DatagramPacket(bs,0,bs.length, InetAddress.getByName("192.168.38.226"),10010);
            if(str.equals("end")){
                break;
            }
            ds.send(dp);
            //发送端获取接收端给的回复:
            byte[] bs2 = new byte[1024];
            DatagramPacket dp2 = new DatagramPacket(bs2,bs2.length);
            ds.receive(dp2);
            byte[] bs3 = dp2.getData();
            int len = dp2.getLength();
            System.out.println("获取的数据为:" + new String(bs3,0,len));
        }
        ds.close();
    }
}

4.2 接收端代码

package udp.demo3;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.util.Scanner;

public class Receiver {
    public static void main(String[] args) throws IOException {

        DatagramSocket ds = new DatagramSocket(10010);
        Scanner sc = new Scanner(System.in);
        byte[] bs = new byte[1024];
        while(true){
            //表示接收另一端发送的数据:
            DatagramPacket dp = new DatagramPacket(bs,bs.length);
            ds.receive(dp);
            byte[] bs2 = dp.getData();
            int len = dp.getLength();
            String str = new String(bs2, 0, len);
            System.out.println("获取的数据为:" + str);
            //接收数据之后,给另一端给出一个答案和反馈:
            System.out.println("请录入您要回复的信息:");
            String str2 = sc.nextLine();
            byte[] bs3 = str2.getBytes();
            DatagramPacket dp2 = new DatagramPacket(bs3,0,bs3.length,dp.getAddress(),dp.getPort());
            ds.send(dp2);
            if(str2.equals("end")){
                break;
            }
        }
        ds.close();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据星历计算卫星位置的方法是比较复杂的,需要用到天文学中的一些计算方法和公式,因此需要一些较为复杂的计算。以下是一个大致的计算流程: 1. 将给定的日期时间转换为儒略日(Julian day)。 2. 根据儒略日计算相应的世纪数。 3. 计算卫星的平近点角(Mean Anomaly)和升交点赤经(Right Ascension of Ascending Node)。 4. 计算卫星的轨道倾角(Inclination)、近地点角距(Argument of Perigee)、半长轴(Semi-Major Axis)等轨道参数。 5. 计算卫星的真近点角(True Anomaly)。 6. 根据卫星的真近点角、轨道参数和世纪数等信息,计算卫星的位置。 下面是一个简单的 C++ 代码示例,可以用来计算给定日期时间的 C01 卫星位置: ```c++ #include <iostream> #include <cmath> using namespace std; const double PI = 3.14159265358979323846; const double GM = 3.986005e14; const double OMEGA_E = 7.2921151467e-5; const double MU_GPS = 3.986005e14; const double C_GPS = 299792458.0; // 计算儒略日 double julian_day(int year, int month, int day, int hour, int minute, int second) { int a = (14 - month) / 12; int y = year + 4800 - a; int m = month + 12 * a - 3; int jdn = day + (153 * m + 2) / 5 + 365 * y + y / 4 - y / 100 + y / 400 - 32045; double jd = jdn + ((double)hour - 12) / 24 + (double)minute / 1440 + (double)second / 86400; return jd; } // 计算卫星位置 void satellite_position(double t, double *pos) { // 从星历中读取轨道参数等信息 double a = 26559700.0; double e = 0.008777161321; double i = 0.9757632172; double O = 0.5405171530; double w = 3.510029399; double M = 0.0; double n = sqrt(MU_GPS / pow(a, 3)); double t0 = 0.0; // 计算平近点角 double E = M + e * sin(M); double E0 = E; while (abs(E - E0) > 1e-12) { E0 = E; E = M + e * sin(E); } double v = 2 * atan(sqrt((1 + e) / (1 - e)) * tan(E / 2)); double r = a * (1 - e * cos(E)); // 计算卫星位置 double x = r * (cos(O) * cos(w + v) - sin(O) * sin(w + v) * cos(i)); double y = r * (sin(O) * cos(w + v) + cos(O) * sin(w + v) * cos(i)); double z = r * sin(w + v) * sin(i); double dt = t - t0; pos[0] = x * cos(OMEGA_E * dt) + y * sin(OMEGA_E * dt); pos[1] = -x * sin(OMEGA_E * dt) + y * cos(OMEGA_E * dt); pos[2] = z; } int main() { int year = 2020; int month = 12; int day = 23; int hour = 23; int minute = 0; int second = 0; double jd = julian_day(year, month, day, hour, minute, second); double t = (jd - 2451545.0) / 36525.0; double pos[3]; satellite_position(t, pos); cout << "C01卫星位置:" << endl; cout << "X = " << pos[0] << " m" << endl; cout << "Y = " << pos[1] << " m" << endl; cout << "Z = " << pos[2] << " m" << endl; return 0; } ``` 注意:由于卫星位置的计算涉及很多天文学中的参数和公式,因此以上代码仅供参考,具体实现需要根据实际情况进行调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值