首页
资源库
留言板
站点统计
Search
1
[Vue] Vue 使用ElementUI组件
123 阅读
2
[Java] 安装JDK8
93 阅读
3
[mysql] mysql 安装
93 阅读
4
[Java] 发送消息
91 阅读
5
[C语言] 游戏贪吃蛇
87 阅读
Tools
编程
C/C++
Java
mySQL
python
PHP
Vue
嵌入式系统编程
HTML
数据结构
TypeScript
登录
Search
标签搜索
Java
SpringBoot
数据结构
C/C++
mysql
Vue
游戏
tools
TomCat
redis
linux
arm
嵌入式系统
PHP
maven
图床
github
IDEA
jar
war
星如雨
累计撰写
41
篇文章
累计收到
2
条评论
首页
栏目
Tools
编程
C/C++
Java
mySQL
python
PHP
Vue
嵌入式系统编程
HTML
数据结构
TypeScript
页面
资源库
留言板
站点统计
搜索到
41
篇与
的结果
2022-12-28
[TypeScript] TS01
TypeScriptTypeScript 与JavaScript的区别TypeScript (TS)是JavaScript(JS) 的一个超集(即:JavaScript所拥有的TypeScript同样拥有),TypeScript 在 JavaScript基础上进行了类型的支持,使开发更高效TypeScript是静态类型的编程语言,JavaScript是动态类型编程语言静态类型:在编译期进行类型检查动态类型:在执行期进行类型检查编译和执行的顺序:先编译再运行因此typeScript相对于JavaScript更早发现代码的问题安装TypeScript由于node.js/浏览器仅认识js,需要将TS转译成JS代码,使代码能执行npm install -g typescript # 检查是否安装成功 由于typescript提供tsc命令 tsc -v==问题==由于控制台认为tsc命令不是个安全的命令,需要执行一管理员身份运行修改:以管理员身份运行 PowerShell输入 set-ExecutionPolicy RemoteSigned输入是或者Y 即可创建目录(自己命名)==尽量用英文命名==在目录下面创建hello.ts并写入console.log("hello TypeScript")编译 tsc hello.ts在同级目录下会自动生成一个hello.js 的文件运行 node hello.js将会运行 hello.js 的代码简化运行ts 命令由于执行 ts代码需要先执行 tsc 再执行node 分为两步,为了方便将这两步合并安装 ts-node 包npm install -g ts-node运行时ts-node hello.ts==注意==:在内部将ts转化为js代码, 但没有生成js文件,直接运行了这个转化的js代码,并不是单纯的将两步合并起来TypeScript常用类型TS类型提示JS中有类型number/string 但在并不会检查是否发生变化,因此会导致问题的出现,而且编译器不会进行提示TS会进行代码错误提示TS类型注解// let 变量名:变量类型 = 变量值 let age: number = 20TS基础类型JS中有的 原始类型number/string/boolean/null/undefined/symbol对象类型Object(数组,对象,函数)TS中增加联合类型,自定义类型(类型别名),接口,元组,字面量类型,枚举,void,any等// 简单类型 let age: number = 20; let name: string = "张三"; let sex: boolean = true; //... // 复杂 let family: string[] = ["爸爸", "妈妈"] // 定义一个字符串类型的数组 let family: Array(string) = ["爸爸", "妈妈"] // 定义一个字符串类型的数组 // 联合类型 let data: (number | string)[] = [12, "李四", "王五"]//定义一个字符串或者是数值类型的数组 // 注意:| 的优先级没有[] 高,因此(number | string)[] 和 number | string[]是两种结果 // 类型别名 ~type 名称 = 类型~ type NumberOrString = number | string let data: NumberOrString = 12 let data2: NumberOrString = "12" // 函数类型 function add(num1: number, num2: number): number{ return num1 + num2; } // 表达式类型 const add = (num1: number, num2: number): number => { return num1 + num2; } // void 类型表示该函数没有返回值 // 可选参数,注意:可选参数只能出现在必选参数的后面 function slice(str: string, start:number, end?:number): string {} // 接口:interface 接口名{} interface Person { name :string age: number } let P:Person = {name:"张三", age:18}type 和 interface 的区别type是个类型赋值,因此在定义时需要用 = 进行赋值,可以对任意类型进行别名interface 是个类 不需要用=,只能对对象使用,其他类型不能使用,接口中可以使用继承接口继承interface Point2D {x: number,y: number}; interface Point3D extends Point2D {z: number}元组由于数组的不定长的原因,在某些场景下虽然数组能满足要求,但不适用,例如定位经纬度等,因此需要有定长的数组来实现。元组:一种特殊的数组,知道数组中的元素个数,以及特定索引对应的类型let Position: [number, number] = [39, 144] // 元组中只能出现两元素,并且两个都是number类型TS中类型推论能推导出当前变量或对象的类型或者拥有的属性,即可省略类型注解在变量值初始化时在函数返回值时类型检查机制依旧存在TS类型断言在操作DOM时获取标签,但默认是获取的对象所有用的类型均为HTMLElement 所包含的属性为所有标签的公共属性,某些特殊的属性针对特殊标签并没有,因此使用断言获取指定类型的标签,例如:<a href="http://ilstudy.vip" id=“BlogUrl”>星如雨博客</a>let BlogUrl = document.getElementById("BlogUrl");// 获取的类型是HTMLElement // 使用 BlogUrl.href 的时候会报错 // 使用断言 let BlogUrl = document.getElementById("BlogUrl") as HTMLAnchorElement; // 再次使用 BlogUrl.href正常 //另一种写法, 不建议这种写法 会和 react 语法冲突 let BlogUrl = <HTMLAnchorElement>document.getElementById("BlogUrl");控制台查看指定元素的类型$0, 使用 console.dir($0) 手动查看当前元素具体类型,在列表的最后字面量类型变量使用const关键字let str1 = "123" // 类型为string const str2 = "123" // 类型为"123" // const 是将值直接作为了类型,const声明的为常量,值不能发生改变 // 使用场景,一般与联合类型使用,确定某些值,中进行选择枚举类型是字面量类型和联合类型共同的结果,枚举类型=字面量类型+联合累心enum Direction{Up,Down,Left,Right}; let dir: "Up" | "Down" | "Left" | "Right"; // 访问枚举成员 Direction.Up; //... //枚举成员的值 默认是从0开始1,2,3,....自增的关系 enum Direction{Up = 10,Down,Left,Right};//从10开始11,12,13,....自增的关系 //字符串类型的枚举 enum Direction{Up= "Up",Down = "Down",Left = "Left",Right = "Right"};//字符串类型没有默认自增长any类型any类型取消所有的变量类型判断,变成为任意类型,代码也不会给予相应的提示,失去TS的代码类型检查功能,容易出现错误。对于刚命名的 变量没有给类型,并且没有初始值时,此时的类型为any类型typeof获取变量的类型代码上下文使用,类似于别名变量类型:利用类型推论,自动识别变量类型TS中Class关键字class Person{ // 属性或方法 } let p = new Person()class 构造函数class Person{ // 构造函数没有返回值 constructor(/*变量*/){ // this.变量名 ;访问该类中的属性和方法 } }class 继承extends js中代码继承父类,公共属性使用继承,父级是 class类型属性与方法的继承,重写implements 实现接口 TS中特有,父级是interface类型属性与方法的继承、实现class 修饰符修饰符等级public公共的(所有位置均可访问),默认修饰符protected受保护的(类内和子类中可用,实例对象无法使用)private私有的(当前类中可见,实例化对象和子类中不能使用)readonly 关键字只能在构造函数中修改被readonly修饰的属性,其他地方无法修改被readonly修饰的属性的属性值,被readonly修饰的属性可以有默认属性值readonly只能修饰属性,不能修饰方法TS类型兼容性两种类型系统结构化类型系统(Structural Type System)标明类型系统(Nominal Type System)TS中采用的是结构化类型系统:类型检查关注的是值所具有的属性,即是两个对象所具有的相同的属性以及属性类型,则认为他们是相同类型的,对于对象来讲y对象所具有的属性,包含x所具有的属性,在x中都有,则说明x兼容y(属性多的可以赋值给属性少的)class point{x:nuumber,y:number} class point2D{x:nuumber,y:number} class point3D{x:nuumber,y:number,z:number} // pint类与point2D类只有类名不同,但具有相同的属性,则认为point和point2D是相同的属性以及属性类型是否相同 let p1:point = new point2D(); let p2:point = new point3D(); //向上兼容接口兼容性interface和class 相似,并且可以相互兼容函数兼容性函数:参数个数,参数类型,函数返回值参数个数兼容:参数少的可以赋值给参数多的参数类型兼容:相同位置的参数进行兼容,原始类型或对象类型(对象为参数兼容)返回值兼容:返回值类型相同的相互兼容,返回值为对象的参照对象属性个数兼容
2022年12月28日
4 阅读
0 评论
0 点赞
2022-08-25
[数据结构] 特殊线性表:广义表
广义表广义表又称列表(List),是 n≥0 个元素 (a1,a2,a3,...,an) 的优先序列,其中ai是原子数据类型或者是一个广义表,记LS=(a1,a2,a3,...,an)LS : 表示表名ai : 表示元素,通常小写字母表示元素是原子数据类型,大写字母表示元素是广义表广义表表头广义表的第一个元素(a1),可以是一个原子类型也可以是一个广义表广义表表尾广义表中除了第一个元素之外的其他元素组成的广义表 --> 表尾是一个表广义表可以使用 "()" 表示,其中()的最深层数表示表的深度,表的次序 :一个直接前驱,一个直接后继例如LS = (a1) : LS中有一个元素 表头为 a1,表尾为 ()LS = (a1, a2) :LS中有两个元素 表头为 a1,表尾为 (a2)LS = (a1, ()) :LS中有两个元素 表头为 a1,表尾为 (())LS = (a1, a2,()) :LS中有三个元素 表头为 a1,表尾为 (a2,())表的共享两个广义表 A,B, 其中A和 B 的关系 B = (A)表的递归有一个广义表 A,其中 A = (A)
2022年08月25日
30 阅读
0 评论
0 点赞
2022-08-12
[数据结构] 线性表之链式存储:单链表
定义线性表的链式存储又称单链表,它是只通过一组任意的存储单元来存储线性表的数据元素。为建立数据元素之间的线性关系,每个链表节点除了存放元素自身的信息外,还需要存放指向其后继的指针。typedef struct Node{ ElementType data; // 数据域,存放数据 struct Node *next; // 指针域,存放其后继节点的地址 }LNode;头指针和头结点的区别不管带不带头节点,头指针始终指向链表的第一个节点,而头结点是带头结点的链表中的第一个节点,节点数据域通常不存储信息。头结点的有点:由于第一个数据节点的位置被存放在头结点的指针域中,云次在链表的第一个位置上的操作和在表的其他位置操作一致,无需进行特殊处理。无论链表是否为空,其头指针都指向头结点的非空指针(空表中头结点的指针域为空),因此空表和非空表的处理也得到了统一。链表基本操作InitLinkList(&L); // 初始化链表 BeforeHeader(&L, data); // 头插法 AfterHeader(&L, data); // 尾插法 BeforeInsert(p, data); // p 节点之前插入 AfterInsert(p, data); // p 节点之后插入 BeforeDelete(p, &data); // 删除 p 节点之前节点 AfterDelete(p, &data); // 删除 p 节点之后节点 ...特殊链表双链表循环链表循环双链表静态链表
2022年08月12日
30 阅读
0 评论
0 点赞
2022-08-06
[数据结构] 王道数据结构2023 P18_03
问题描述对长度为n的顺序表L,编写一个时间复杂度为O(n),空间复杂度为O(1)的算法,该算法删除线性表中所有值为x的数据元素实现代码bool DeleteSelectX(SeqList &L,ElementType x){ if(L.lenght == 0){ printf("线性表为空\n"); return false; } int i,j; for(i = 0,j = 0;i < L.lenght;i++){ if(L.data[i] != x){ L.data[j] = L.data[i]; j++; } } L.lenght = j; return true; }全部代码#include <stdio.h> #include <stdbool.h> #include <stdlib.h> #define ElementType int #define InitSize 100 int arr[] = {1,2,3,4,1,6,1,8,9,0}; typedef struct { ElementType *data; int MaxLen,lenght; }SeqList; void InitSeqList(SeqList &L){ L.data = (ElementType *)malloc(sizeof(ElementType) * InitSize); L.MaxLen = InitSize; L.lenght = 0; } bool InsertELem(SeqList &L,int i,ElementType data){ if(i < 1 || i > L.lenght + 1){ printf("位置不合法\n"); return false; } if(L.lenght + 1 > L.MaxLen){ printf("线性表已满\n"); return false; } for(int j = L.lenght;j >= i;j--){ L.data[j] = L.data[j - 1]; } L.data[i - 1] = data; L.lenght += 1; return true; } void ShowList(SeqList L){ for(int i = 0;i < L.lenght;i++){ printf("%d ", L.data[i]); } printf("\n"); } bool DeleteSelectX(SeqList &L,ElementType x){ if(L.lenght == 0){ printf("线性表为空\n"); return false; } int i,j; for(i = 0,j = 0;i < L.lenght;i++){ if(L.data[i] != x){ L.data[j] = L.data[i]; j++; } } L.lenght = j; return true; } int main() { SeqList L; InitSeqList(L); for(int i = 0;i < 10;i++){ InsertELem(L,i + 1, arr[i]); } DeleteSelectX(L,1); ShowList(L); return 0; }
2022年08月06日
32 阅读
0 评论
0 点赞
2022-08-06
[数据结构] 线性表之顺序存储:顺序表
顺序表定义线性表的顺序存储又称顺序表。它是用一组地址连续的存储单元依次存储线性表的数据元素,从而使得逻辑上相邻的两个元素在物理位置上也相邻。{message type="warning" content="线性表中元素的位序是从1开始的,但数组的下标是从0开始的"/}静态数组和动态数组的区别一维数组可以是静态分配的,也可以是动态分配的。静态分配由于数组大小和空间已经固定,所以一旦空间占满,在加入新的数据就会产生 数据溢出,进而导致程序运行崩溃。动态分配存储数组的空间是由程序执行过程通过动态存储分配语句分配的,一旦数据空间沾满,就可以另辟新的一块更大的存储空间,用以代替原来的存储空间,达到扩充空间的目的。顺序表空间分配#define ElementType int #define MaxSize 100 // 静态空间分配 typedef struct { ElementType data[MaxSize]; // 定义顺序表元素 int lenght; // 当前元素长度 }SeqList; // 动态空间分配 typedef struct { ElementType *data; // 定义顺序表元素 int MaxLen; // 顺序表最大长度 int lenght; // 当前元素长度 }SeqList;顺序表优点随机访问,通过首地址和元素位序可快速找到指定元素存储密度高,每个节点只存储数据元素逻辑上相邻的元素物理上也相邻顺序表缺点插入和删除需要移动大量元素需要连续内存空间
2022年08月06日
33 阅读
0 评论
0 点赞
2022-08-05
[数据结构] 王道数据结构2023 P18_02
问题描述设计一个高效算法,将顺序表L的所有元素逆置,要求算法的空间复杂度为O(1)问题分析无代码实现bool ReverseList(SeqList &L){ if(L.lenght == 0){ printf("内容为空\n"); return false; } ElementType temp; for(int i = 0,j = L.lenght - 1;i < j;i++,j--){ temp = L.data[i]; L.data[i] = L.data[j]; L.data[j] = temp; } return true; }算法分析无时间复杂度 O(n)空间复杂度 O(1)完整代码#include <stdio.h> #include <stdbool.h> #include <stdlib.h> #define ElementType int #define InitSize 100 int arr[] = {1,2,3,4,5,6,7,8,9,0}; typedef struct { ElementType *data; int MaxLen,lenght; }SeqList; void InitSeqList(SeqList &L){ L.data = (ElementType *)malloc(sizeof(ElementType) * InitSize); L.MaxLen = InitSize; L.lenght = 0; } bool InsertELem(SeqList &L,int i,ElementType data){ if(i < 1 || i > L.lenght + 1){ printf("位置不合法\n"); return false; } if(L.lenght + 1 > L.MaxLen){ printf("线性表已满\n"); return false; } for(int j = L.lenght;j >= i;j--){ L.data[j] = L.data[j - 1]; } L.data[i - 1] = data; L.lenght += 1; return true; } bool ReverseList(SeqList &L){ if(L.lenght == 0){ printf("内容为空\n"); return false; } ElementType temp; for(int i = 0,j = L.lenght - 1;i < j;i++,j--){ temp = L.data[i]; L.data[i] = L.data[j]; L.data[j] = temp; } return true; } void ShowList(SeqList L){ for(int i = 0;i < L.lenght;i++){ printf("%d ", L.data[i]); } printf("\n"); } int main() { SeqList L; InitSeqList(L); for(int i = 0;i < 10;i++){ InsertELem(L,i + 1, arr[i]); } if(!ReverseList(L)){ printf("线性表反转失败\n"); }else{ printf("线性表反转成功:"); ShowList(L); } return 0; }
2022年08月05日
29 阅读
0 评论
0 点赞
2022-08-05
[数据结构] 王道数据结构2023 P18_01
问题描述从顺序表中删除具有最小值的元素(假设唯一)并由函数返回被删除的值。空出的位置由最后一个元素填补,若顺序表为空,则显示出错信息并退出运行。问题分析无代码实现bool DeleteMin(SeqList &L,ElementType &min){ if(L.lenght == 0){ printf("顺序表为空"); return false; } int flag = 0; for(int i = 0;i < L.lenght;i++){ if(L.data[i] < L.data[flag]){ flag = i; } } min = L.data[flag]; if(flag != L.lenght - 1){ L.data[flag] = L.data[L.lenght - 1]; } L.lenght -= 1; return true; }算法分析无时间复杂度 O(n)空间复杂度 O(1)完整代码#include <stdio.h> #include <stdbool.h> #include <stdlib.h> #define ElementType int #define InitSize 100 int arr[] = {1,2,3,4,5,6,7,8,9,0}; typedef struct { ElementType *data; int MaxLen,lenght; }SeqList; void InitSeqList(SeqList &L){ L.data = (ElementType *)malloc(sizeof(ElementType) * InitSize); L.MaxLen = InitSize; L.lenght = 0; } bool InsertELem(SeqList &L,int i,ElementType data){ if(i < 1 || i > L.lenght + 1){ printf("位置不合法\n"); return false; } if(L.lenght + 1 > L.MaxLen){ printf("线性表已满\n"); return false; } for(int j = L.lenght;j >= i;j--){ L.data[j] = L.data[j - 1]; } L.data[i - 1] = data; L.lenght += 1; return true; } bool DeleteMin(SeqList &L,ElementType &min){ if(L.lenght == 0){ printf("顺序表为空"); return false; } int flag = 0; for(int i = 0;i < L.lenght;i++){ if(L.data[i] < L.data[flag]){ flag = i; } } min = L.data[flag]; if(flag != L.lenght - 1){ L.data[flag] = L.data[L.lenght - 1]; } L.lenght -= 1; return true; } int main() { SeqList L; InitSeqList(L); for(int i = 0;i < 10;i++){ InsertELem(L,i + 1, arr[i]); } int min; if(DeleteMin(L,min)){ printf("删除元素:%d\n", min); for(int i = 0;i < L.lenght;i++){ printf("%d ", L.data[i]); } }else{ printf("删除失败\n"); } return 0; }
2022年08月05日
35 阅读
0 评论
0 点赞
2022-08-05
[数据结构] 线性表
线性表的定义线性表是具有n个数据元素的有限序列,其中n为线性表的长度,当n=0时,线性表是空表,若用L表示线性表:L = {a1,a2,a3,...,an}其中a1为第一个数据元素,又称表头元素,an为最后一个数据元素,又称表尾元素;除第一个元素外,每个元素都有唯一的前驱;除最后一个元素,每个元素都有唯一的后继。线性表的特点表中元素个数有限表中元素具有逻辑上的顺序性,表中元素都有先后顺序表中元素都是数据元素,每个元素都是单个元素表中元素数据类型相同,即:每个元素占有空间大小相同表中元素具有抽象性,即:仅讨论元素之间的逻辑关系,而不考虑元素究竟表达什么内容线性表的基本操作InitList(&L) : 初始化表ListInsert(&L,i,data) : 插入操作,将元素插入到第i个位置ListDelete(&L,i,&data) : 删除操作,删除第i个元素ListModify(&L,i,data) : 修改操作ListFindByValue(&L,data) : 查找操作,按值查找ListFindByIndex(&L,i,&data) : 查找操作,按位置查找ListDestory(&L) : 销毁表getLength(L) : 获取表长度Empty(L) : 线性表判空
2022年08月05日
25 阅读
0 评论
0 点赞
2022-06-15
[QT] QT SQLite 实现增删改查
1.在工程文件下使用sql(*.pro 输入QT+=sql)2.初始化页面设计3. 写代码3.1 连接数据库的头文件书写#ifndef CONNECTION_H #define CONNECTION_H #include <QSqlDatabase> #include <QMessageBox> #include <QSqlQuery> static bool CreateConnectDatabase(){ QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE"); db.setDatabaseName("test.db"); if( !db.open() ) { QMessageBox box; box.setText("open database fail"); return false; } QSqlQuery query; query.exec("create table SQLite(id integer primary key, name varchar(20) )"); return true; } #endif3.2 主函数调用#include <QtGui/QApplication> #include "mainwindow.h" #include "connection.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); if(! CreateConnectDatabase() ){ return false; } MainWindow w; w.show(); return a.exec(); }3.3 窗口头文件定义槽函数private slots: void on_lineEdit_1_textChanged(QString value); void on_lineEdit_2_textChanged(QString value); void on_Button_1_clicked(); void on_Button_2_clicked(); void on_Button_3_clicked(); void on_Button_4_clicked(); void on_Button_5_clicked();3.4 实现槽函数void MainWindow::on_lineEdit_1_textChanged(QString value){ idValue = value; } void MainWindow::on_lineEdit_2_textChanged(QString value){ nameValue = value; } // show void MainWindow::on_Button_1_clicked(){ QSqlQuery query; query.exec("select id,name from SQLite"); QStandardItemModel *model = new QStandardItemModel; this->ui->tableView->setModel(model); model->setHorizontalHeaderItem(0, new QStandardItem("id")); model->setHorizontalHeaderItem(1, new QStandardItem("name")); int i = 0; while( query.next() ){ ui->label->setText("select ok"); model->setItem(i, 0, new QStandardItem( query.value(0).toString() ) ); model->setItem(i, 1, new QStandardItem( query.value(1).toString() ) ); i += 1; } } void MainWindow::on_Button_2_clicked(){ if(idValue == "" || nameValue == ""){ ui->label->setText("id or name is none"); }else{ QSqlQuery query; query.exec("select id from SQLite where id='" + idValue + "'"); if(! query.next()){ query.exec("insert into SQLite(id, name) values( " + idValue + ",'" + nameValue + "')"); ui->label->setText("insert id=" + QString(idValue) +" success"); ui->lineEdit_1->setText(""); ui->lineEdit_2->setText(""); }else{ ui->label->setText("insert existed"); } } } void MainWindow::on_Button_3_clicked(){ if(idValue == "" || nameValue == ""){ ui->label->setText("id or name is none"); }else{ QSqlQuery query; query.exec("select id from SQLite where id='" + idValue + "'"); if( query.next()){ query.exec("update SQLite set name = '" + nameValue + "' where id=" + idValue ); ui->label->setText("update id=" + QString(idValue) +" success"); ui->lineEdit_1->setText(""); ui->lineEdit_2->setText(""); }else{ ui->label->setText("update not existed"); } } } void MainWindow::on_Button_4_clicked(){ QSqlQuery query; query.exec("delete from SQLite"); ui->label->setText("delete ok"); } void MainWindow::on_Button_5_clicked(){ qApp->quit(); }4 运行此时没有任何数据插入数据 1 123查询数据更新数据 1 456删除数据(删除所有数据)
2022年06月15日
62 阅读
0 评论
0 点赞
2022-05-28
[Java] Socket 点对点通信
SocketSocket 套接字,就是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象。一个套接字就是网络上进程通信的一端,提供了应用层进程利用网络协议交换数据的机制。从所处的地位来讲,套接字上联应用进程,下联网络协议栈,是应用程序通过网络协议进行通信的接口,是应用程序与网络协议栈进行交互的接口 百度百科程序采用多线程方式进行数据发送与接受主类Main.javapackage UDPSocket; public class Main { public static void main(String[] args) { new Receive().start();// 接受数据线程 new Send().start();// 发送数据线程 } }数据发送类class Send extends Thread { public void run() { try { DatagramSocket socket = new DatagramSocket(); Scanner sc = new Scanner(System.in); while (true) { String str = sc.nextLine(); // 输入 logout 退出循环发送消息 if ("logout".equals(str)) break; /** * IP : 数据接收者的IP, * port : 数据接收着的端口 */ String IP = "127.0.0.1"; int port = 6666; DatagramPacket packet = new DatagramPacket( str.getBytes(), str.getBytes().length, InetAddress.getByName(IP), port ); socket.send(packet); } socket.close(); } catch (Exception e) { e.printStackTrace(); } } }数据接受类public class Receive extends Thread { public void run() { try { // 监听端口是否有数据,初始化数据容量 DatagramSocket socket = new DatagramSocket(6666); DatagramPacket packet = new DatagramPacket(new byte[1024], 1024); while(true) { socket.receive(packet);// 接收货物 byte[] arr = packet.getData(); int len = packet.getLength(); String ip = packet.getAddress().getHostAddress(); // 这个IP 为发送者的IP System.out.println("收到来自IP" + ip + "消息:" + new String(arr,0,len)); } } catch (IOException e) { e.printStackTrace(); } } }本地测试
2022年05月28日
29 阅读
0 评论
0 点赞
1
2
...
5