JAVA自学笔记26

1、网络编程

1)用来实现网络互联的不同计算机上运行的程序可以进行数据交换

2)网络模型一般泛指

OSI:(Open System Interconnection)开放系统互联参考模型

TCP/IP参考模型

3)网络编程三要素

IP地址、端口、协议

①IP地址:在TCP/IP协议中网络通信中的计算机的唯一标识号

java提供类InetAddress供使用。

为了方便用4个十进制数表示

网络号段+主机号段

IP分类:

见书

ipconfig–查看本机IP地址

ping ip地址–测试本机与指定的ip地址间的通信是否有问题

特殊的Ip地址:

127.0.0.1–回环地址,表示本机

x.x.x.255–广播地址

x.x.x.0–网络地址

4)InetAddress

无构造方法:{

成员都是静态的

单例设计模式(Runtime)

类中有静态方法返回该类的对象

}

属上述情况中的最后一种

public static InetAddress getByName(String host):

根据主机名或者ip地址表示得到的IP地址对象

InetAdress address=InetAddress.getByName("cc");

String name=address.getHostName();//获取主机名
String ip=address.getHostName();//获取ip地址

5)端口号

每个网络程序都会至少有一个逻辑端口,用于标识进程的逻辑地址,不同 进程的标识

有效端口0~65535,其中0~1024系统使用或保留

6)协议

UDP:将数据源和目的封装成数据包中,不需要建立连接;每个数据包的大小限制在64k;因无连接,是不可靠的协议;不需要建立连接,速度快

TCP:建立连接,形成传输数据的通道:在连接进行大数据量的传输;通过3次握手完成连接,是可靠协议;必须建立连接,效率稍低。

7)socket通信原理

socket–网络套接字

网络上具有唯一标识的IP地址和端口组合在一起才能构成唯一能识别的标识符套接字。

原理机制:

通信的两端都有socket,网络通信其实是Socket之间的通信,数据在两个Socket之间通过IO传输

DatagramPacket (byte[] buf,int length,InetAddress address,int port)

构造包含数据,其长度,远程主机的Ip地址和远程主机的端口号

public void send(DatagramPacket p);

从此套接字发送数据报包。DatagramPacket含将要发送的数据,其长度,远程主机的Ip地址和远程主机的端口号

//UDP协议发送数据
--创建发送端Socket对象
--创建数据,并把数据打包
--调用Socket对象的放松方法发送数据包
--释放资源 //创建发送端Socket对象
DatagramSocket ds=new DatagramSocket(); //创建数据,并把数据打包
byte[] bys="good morning!你好";
int length=bys.length();
InetAddress address=InetAddress.getByName("222,241.111,1");
int port=10086;
DatagramPacket (bys,length,address,port)
//调用Socket对象的发送方法发送数据包
ds.send(dp);
//释放资源
ds.close();

DatagramSocket(int port);//创建数据报套接字并将其绑定到本地主机上的指定端口

public void receive(DatagramPacket p)从此套接字接收数据报包。

//UDP协议接收数据
--创建接受端Socket对象
--创建一个数据包(接收容器)
--调用Socket对象的接收方法接收数据
--解析数据包,并显示在控制台
--释放资源 //创建接受对象
DatagramSocket ds=new DatagramSocket(10086); //创建一个数据包
byte[] bys=new byte[1024];
int length=bys.length;
DatagramPacket dp=new DatagramPacket(bys,length); //调用Socket对象的接收方法接收数据
ds。receive(dp); //解析数据包,并输出到控制台
//public byte[] getData():获取数据缓冲区
//public int getLength();//获取数据的实际长度
byte[] bys2=dp.getData();
int len=dp.getLength();
String s=new String(by2,0,len);
System.out.println(s); ds.close();
//

图解:

//代码优化
public class ReceiveDemo{
public static void main(String args[]){
//创建接收端的Socket对象
DatagramSocket ds=new DatagramSocket(10086); DatagramPacket dp=new DatagramPacket(bys,bys.length); //接收数据
ds.receive(dp); //解析数据,链式编程
String ip=dp.getAddress().getHostAddress();
String s=new String (dp.getData(),0,dp.getLength());
System.out.println(s);
ds.close();
}
} public class SendDemo{
public static void main(String args[]){
byte[] bys="hello".getBytes();
DataPacket dp=new DatagramPacket(bys,bys.length.InetAddress.getByName("192.12.36.8"),10086);
ds.send(dp);
ds.close();
}
}

多次启动接收端将提示该端口已被占用

//发送端的数据来自键盘录入
public class ReceiveDemo{
public static void main(String args[]){
//创建接收端的Socket对象
DatagramSocket ds=new DatagramSocket(10086);
while(true){
byte[] bys=new byte[1024];
DatagramPacket dp=new DatagramPacket(bys,bys.length);
//接收数据
ds.receive(dp); //解析数据,链式编程
String ip=dp.getAddress().getHostAddress();
String s=new String (dp.getData(),0,dp.getLength());
System.out.println(s);
}
}
} public class SendDemo{
public static void main(String args[]){ DatagramSocket ds=new DatagramSocket();
//封装键盘录入数据
BufferedReader ds=new DatagramSocket(); BUfferedReader br=new BufferedReader(new InputStreamReader(System.in));
String line=null;
while((line=br.readLine())!=null){
byte[] bys=line.getBytes();
DataPacket dp=new DatagramPacket(bys,bys.length.InetAddress.getByName("192.12.36.255"),10086);//广播地址
ds.send(dp);}
ds.close();
}
}
//多线程实现聊天室

public class ChatRoom{
public static void main(String args[]){
DatagramSocket ds=new DatagramSocket();
DatagramSocket dsReceive=new DatagramSocket(12300); SendThread st=new SendThread(dsSend);
ReceiveThread(dsReceive); Thread t1=new Thread(st);
Thread t2=new Thread(rt); t1.start();
t2.start();
}
} public class SendThread implements Runnable{
private DatagramSocket ds; public SendThread(DatagramSocket ds){
this.ds=ds;
}
public void run(){
BUfferedReader br=new BufferedReader(new InputStreamReader(System.in));
String line=null;
while((line=br.readLine())!=null){
byte[] bys=line.getBytes();
DataPacket dp=new DatagramPacket(bys,bys.length.InetAddress.getByName("192.12.36.255"),12300);//广播地址
ds.send(dp);}
ds.close(); } } public class ReceiveThread implements Runnable{
private DatagramSocket ds;
public ReceiveThread(DatagramSocket ds){
this.ds=ds;
}
public void run(){
while(true){
byte[] bys=new byte[1024];
DatagramPacket dp=new DatagramPacket(bys,bys.length);
//接收数据
ds.receive(dp); //解析数据,链式编程
String ip=dp.getAddress().getHostAddress();
String s=new String (dp.getData(),0,dp.getLength());
System.out.println(s);
}
}
}

2、TCP

//TCP发送数据
--创建发送端的Socket对象
--获取输出流写数据
--释放资源 public class ClientDemo{
public static void main(String args[]){
Socket s=new Socket(InetAddress.getByName("193.36.14.2"),6811);
//Socket s=new Socket("193.36.14.2",6811);也行 //获取输出流,写数据
public OutputStream getOutputStream() OutputStream os=s.getOutputStream();
os,write("hell0!".getBytes());
s.close();
}
}
//TCP协议接收数据
--创建接收端Socket对象
--监听客户端接收,返回一个对应的Socket对象
--获取输入流,读取数据显示在控制台
--释放资源 ServerSocket ss=new ServerSocket(6811); //监听客户端连接,返回一个对应的Socket对象 Socket s=ss.accept();
//获取输入流显示在控制台
InputStream is=s.getInputStream(); byte[]bys=new byte[1024];
int len=is.read(bys);
String str=new String(bys,0,len);
String ip=s.getInetAddress().getHostAddress();
System.out,println(str); //释放资源
s.close();

图解:

//有反馈的案例

public class ServerDemo{
public static void main(String[] aargs){
//创建服务器Socket对象
ServerSocket ss=new SeverSocket(9999); //监听客户端的连接
Socket s=ss.accept(); //获取输入流
InputStream is=s.getInputStream();
byte[] bs=new byte[1024];
int len=is.read(bys);
String server=new String(bys,0,len);
System.out.println(server); //获取输出值
OutputStream os=s.getOutpitStream();
os.write("数据已收取"。getByte()); //关闭
s.close();
}
} public class ClientDemo{
public static void main(String[] args){
//创建客户端Socket对象
Socket s=new Socket("111.111.1.1",9999); //获取输出流
OutputStream os=s.getOutputStream();
Os.write("今天天气还行".getBytes()); //获取输入流
InputStream is=s.getInputStream();
byte[] bys=new byte[1024];
int len=is.read(bys);
String client=new String(bys,0,len);
System.out.println(client); //释放资源
s.close();
}
}
//客户端键盘录入服务器控制台输出

public class ClientDemo{
public static void main(Stirng[] args){
Socket s=new Socket("192.168.2.92",22222); //键盘录入数据
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
String line=null;
while((line=br.readLine())!=null){
//把通道内的流包装一下
BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));//字节流
String line=null;
while(if("886".equals(line)){
break;
}
(line=br.readLine())!=null){
bw.write(line);
bw.newLine();
bw.flush();
}
//释放资源
s.close();
}
}
} //服务器
public class ServerDemo{
pubic static void main(String[] args){
//创建服务器Socket对象
ServerSocket ss=new ServerSocket(22222); //监听客户端连接
Socket s=ss..accept(); //包装通道内的流
BufferedReader br=new BufferedReader(new InputStreamReader(s.getInputStream()));
String line=null;
while((line=br.readLine())!=null){
System.out.println(line);
} s.close(); }
}
//客户端键盘录入服务器写到文本文件
public class ClientDemo{
pubic static void main(String args[]){
Socket s=new Socket("192.168.12.92",23456); //封装键盘录入
Buffered br=new BufferedReader(new InputStreamReader(System.in)); //封装通道内的数据
BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(
s.getOutputStream()));
String line=null;
While((line=br.readLine())!=null)
if("over".equals(line)){
break;
}
s.close();
}
} public class ServerDemo{
public static void main(String[] args){
//创建服务器Socket对象
ServerSocket ss=new ServerSocket(23456); //监听客户端连接
Socket s=ss.accept(); //封装通道内的数据
BufferedReader br=new BufferedReader(new InputStreamReader(s.getInputStream())); //封装文本文件
BufferedWriter bw=new BufferedWriter(new FileWriter("a.txt")); String line=null;
while((line=br.readLine())!=null){
bw.write(line);
bw.newLine();
bw.flush();
}
bw,close();
s.close();
}
}
//客户端读取文本文件服务器控制台输出
public static ClientDemo{
public static void main(String[] args){
//创建Socket对象
Socket s=new Socket("198.168.12.92",34567); //封装文本文件
BufferedReader br=new BufferedReader(new FileReader("InetAddressDemo.java")); //封装通道内的流
BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
String line=null;
while((line=br.readLine())!=bull){
bw.write(line);
bw.newLine();
bw.flush(); } br.close();
s.close();}
} public class ServerDemo{
public static void main(String[] args){
//创建服务器Socket对象
ServerSocket ss=new ServerSocket(34567); //监听客户端连接
Socket s=ss.accept(); //封装通道内的流
BufferedReader br=new BufferedReader(new InputStreamReader{s.getInputStream())); String line=null;
while((line=br.readLine())!=null){
System.out.println(line);
}
}
s.close();
}
//客户端文本文件,服务器输出文本文件

public class UploadClient{
public static void main(String args[]){
//创建客户端Socket对象
Socket s=new Socket("192.188.12.92",11111);
//封装文本文件
BufferedReader br=new BufferedReader(new FileReader("InetAddressDemo.java")); //封装通道内流
BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(s.getOutputStream())); String line=null;
while((line=br.readLine())!=null){
br.close();
s.close(); }
} public class Uploadserver{
public static void main(String args[]){
//创建服务器的Socket对象
ServerSocket ss=new ServerSocket(11111); //监听客户端连接
Socket s=ss.accept(); //封装通道内的流
BufferedReader br=new BufferedReader(new InputStramReader(s.getInputStream())); //封装文本文件
BufferedWriter bw=new BufferedWriter(new FileWriter("Copy.java")); String line=null;
while((line=br.readLine())!=bull){
bw.write(line);
bw.newLine();
bw.flush(); bw.close();
s.close(); }
}
//TCP上传文本文件并给出反馈
注意:读取文本文件是可以以null作为结束信息的,但是通道内是不能这样结束信息的。所以服务器根本就不知道结束了,而客户端还在等服务器给反馈,因此就相互等待了。
a.自定义结束标记
b.shutdownInput()--禁用此套接字的输出流,对于TCP套接字,任何以前写入的数据都将被发送,并且后跟TCP的正常终止序列。 以此为准
public class UploadClient {
public static void main(String[] args) throws IOException {
// 创建客户端Socket对象
Socket s = new Socket("192.168.12.92", 11111); // 封装文本文件
BufferedReader br = new BufferedReader(new FileReader(
"InetAddressDemo.java"));
// 封装通道内流
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
s.getOutputStream())); String line = null;
while ((line = br.readLine()) != null) { // 阻塞
bw.write(line);
bw.newLine();
bw.flush();
} //自定义一个结束标记
// bw.write("over");
// bw.newLine();
// bw.flush(); //Socket提供了一个终止,它会通知服务器你别等了,我没有数据过来了
s.shutdownOutput(); // 接收反馈
BufferedReader brClient = new BufferedReader(new InputStreamReader(
s.getInputStream()));
String client = brClient.readLine(); // 阻塞
System.out.println(client); // 释放资源
br.close();
s.close();
}
} public class UploadServer {
public static void main(String[] args) throws IOException {
// 创建服务器端的Socket对象
ServerSocket ss = new ServerSocket(11111); // 监听客户端连接
Socket s = ss.accept();// 阻塞 // 封装通道内的流
BufferedReader br = new BufferedReader(new InputStreamReader(
s.getInputStream()));
// 封装文本文件
BufferedWriter bw = new BufferedWriter(new FileWriter("Copy.java")); String line = null;
while ((line = br.readLine()) != null) { // 阻塞
// if("over".equals(line)){
// break;
// }
bw.write(line);
bw.newLine();
bw.flush();
} // 给出反馈
BufferedWriter bwServer = new BufferedWriter(new OutputStreamWriter(
s.getOutputStream()));
bwServer.write("文件上传成功");
bwServer.newLine();
bwServer.flush(); // 释放资源
bw.close();
s.close();
}
}
//TCP协议上传图片,使用字节流

public class UploadServer{
public static void main(String args){
//创建服务器Socket对象
ServerSocket ss=new ServerSocket(19191);
//监听客户端连接
Socket s=ss.accept();
//封装通道内流
BufferedInputStream bis=new BufferedInputStream(s.getInputStream());
//封装图片文件
BufferedOutoutStream bos=new BufferedOutputStream{
new FileOutpuutStream("mn.jpg"); byte[] bys=new byte[1024];
int len=0;
while((len=bis.read(bys))!=-1){
bos.write(bys,0,len);
}
//给一个反馈
OutputStream os=s.getOurStream();
os.write("success".getBytes()); bos.close();
s.close();
}
}
} public class UploadClient{
public static void main(String args){
//创建客户端Socket对象
Socket s=new Socket("192.168.12.92"),19191); //封装图片文件
BufferedInputStream bis=new BufferedInputStream(new FileInputStrean(a.jpg));
//封装通道内的流
BufferedOutputStream bos=new BufferedOutputStream(s.getOutputStream()); int len=0;
while((len=bis.read(bys))!=-1){
bos.write(bys,0,len);
bos.flush();//一定要刷新
} s.shutdownOutput(); //读取反馈
InputStream is=s.getInputStream();
byte[] bys2=new byte[1024];
int len2=is.read(bys2);
String client=new String(by2,0,len2);
System.out.println(client); //释放资源
bis.close();
s.close(); } }

多个客户端上传至一个服务器

it.cast-15

JAVA自学笔记26的更多相关文章

  1. JAVA自学笔记09

    JAVA自学笔记09 1.子类的方法会把父类的同名方法覆盖(重写) 2.final: 1)可修饰类.方法.变量 2)修饰类时:此时该类变为最终类,它将无法成为父类而被继承 3)修饰方法时:该方法将无法 ...

  2. JAVA自学笔记05

    JAVA自学笔记05 1.方法 1)方法就是完成特定功能的代码块,类似C语言中的函数. 2)格式: 修饰符 返回值类型 方法名(参数类型 参数名1,参数类型 参数名2,-){ 函数体; return ...

  3. JAVA自学笔记06

    JAVA自学笔记06 1.二维数组 1)格式: ①数据类型[][]数组名 = new 数据类型[m][n]; 或 数据类型[]数组名[]=new 数据类型[m][n]; m表示这个二维数组有多少个一维 ...

  4. JAVA自学笔记04

    JAVA自学笔记04 1.switch语句 1)格式:switch(表达式){ case 值1: 语句体1; break; case 值2: 语句体2; break; - default: 语句体n+ ...

  5. JAVA自学笔记07

    JAVA自学笔记07 1.构造方法 1) 例如:Student s = new Student();//构造方法 System.out.println(s);// Student@e5bbd6 2)功 ...

  6. JAVA自学笔记10

    JAVA自学笔记10 1.形式参数与返回值 1)类名作为形式参数(基本类型.引用类型) 作形参必须是类的对象 2)抽象类名作形参 需要该抽象类的子类对象,通过多态实现 3)接口名为形参 需要的是该接口 ...

  7. JAVA自学笔记13

    JAVA自学笔记13 1.StringBuffer类 1)线程安全的可变字符序列 线程安全(即同步) 2)StringBuffer与String的区别:一个可变一个不可变 3)构造方法: ①publi ...

  8. JAVA自学笔记11

    JAVA自学笔记11 1:Eclipse的安装 2:用Eclipse写一个HelloWorld案例,最终在控制台输出你的名字 A:创建项目 B:在src目录下创建包.cn.itcast C:在cn.i ...

  9. JAVA自学笔记14

    JAVA自学笔记14 1.正则表达式 1)是指一个用来描述或者匹配一系列符合某个句法规则的字符串的单个字符串.其实就是一种规则.有自己的特殊应用 2)组成规则: 规则字符在java.util.rege ...

随机推荐

  1. Java集合源码学习(一)Collection概览

    1.集合框架 Java集合框架包含了大部分Java开发中用到的数据结构,主要包括List列表.Set集合.Map映射.迭代器(Iterator.Enumeration).工具类(Arrays.Coll ...

  2. java进阶书籍推荐(不包括基础)

    个人认为看书有两点好处: 能出版出来的书一定是经过反复的思考.雕琢和审核的,因此从专业性的角度来说,一本好书的价值远超其他资料 对着书上的代码自己敲的时候方便 “看完书之后再次提升自我的最好途径是看一 ...

  3. 正则表达式匹配URL或者网址

    正则表达式 (http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])? ...

  4. libsecp256k1 与 openssl ecdsa

    1. 历史 区块链节点在接收到的用户发送的交易时,首先会验证交易所涉及utxo的可用性.方法是验证用户签名的合法性,涉及的签名算法就是secp256k1,一种椭圆曲线加密算法. 长期以来,实现了该算法 ...

  5. Docker技术底层架构剖析

    [Docker  底层技术] docker底层的 2 个核心技术分别是 Namespaces 和 Control groups 在操作系统中,网络配置,进程,用户,IPC(进程之间的调用)等信息之间的 ...

  6. Codeforces Gym100543B 计算几何 凸包 线段树 二分/三分 卡常

    原文链接https://www.cnblogs.com/zhouzhendong/p/CF-Gym100543B.html 题目传送门 - CF-Gym100543B 题意 给定一个折线图,对于每一条 ...

  7. String.getBytes()和String.tocharArray(),字节数组和字符数组的区别

    String.getBytes()是将字符串转化为一个字节数组.而String.toCharArray()是将一个字符串转化为一个字符数组. [例如] byte bys[] ="国庆60周年 ...

  8. netty04(重点来了、指定某个客户端发信息或者群发)小声嘀咕~~我也是从零开始学得、、、想学习netty的又不知道怎么下手的童鞋们~~

    还是和上几篇一样,先给出前面笔记的连接,有没看的可以去看看再来! netty01   . netty02  .netty03 看到这里.你基本上可以使用netty接受信息和根据对应的信息返回信息了 接 ...

  9. orleans exception序列化

    options.FallbackSerializationProvider = typeof(ILBasedSerializer).GetTypeInfo();

  10. 最接近的三数之和(给定一个包括 n 个整数的数组 nums 和 一个目标值 target。找出 nums 中的三个整数, 使得它们的和与 target 最接近。返回这三个数的和)

    例如,给定数组 nums = [-1,2,1,-4], 和 target = 1. 与 target 最接近的三个数的和为 2. (-1 + 2 + 1 = 2). 思路:首先对数组进行排序     ...