一,Charset
1,字符集
-编码:字符串---字节数组
-解码:字节数组---字符串
package com.momo.demo;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
/*
- Charset中的编码和解码
- 编码器:
- CharsetEncoder newEncoder() 为此字符集构造一个新的编码器。
- 解码器:
- CharsetDecoder newDecoder() 为此字符集构造一个新的解码器。
- /
public class Demo1 {public static void main(String[] args) throws CharacterCodingException {// SortedMap keys = map.keySet();for (String key : keys) {Charset value = map.get(key);System.out.println(key+"--"+value);}// Set> entries = map.entrySet();
for (Map.Entry entry : entries) {
System.out.println(entry.getKey()+"--"+entry.getValue());
}*/
Charset cs = Charset.forName("GBK"); //获取编码器 CharsetEncoder ce = cs.newEncoder(); //获取解码器 CharsetDecoder cd = cs.newDecoder(); CharBuffer buf = CharBuffer.allocate(1024); buf.put("默默真帅"); buf.flip(); //编码 ByteBuffer buf2 = ce.encode(buf); for (int i = 0; i < 8; i++) { System.out.println(buf2.get()); } //解码 buf2.flip(); CharBuffer buf3 = cd.decode(buf2); System.out.println(buf3); System.out.println("-----------------"); Charset cs2 = Charset.forName("UTF8"); buf2.flip(); CharBuffer cb2 = cs2.decode(buf2); System.out.println(cb2);
}
}
二,网络编程
1,概述
-计算机网络?
是指把地理位置不同的具体独立功能的多个计算机以及外部设备,通过
通信线路链接起来,在网络操作系统,网络管理软件以及网络通信协议
的管理和协调下,实现在原共享和信息传递的计算机系统。
2,网络编程
-就是用来实现互联网上互联的不同的计算机上运行的程序之间可以进行数据交换。
3,网络模型
-网络模型用来规定计算机网络上的计算机以什么规则进行通信。
-网络模型一般指:OSI七层参考模型和TCP/IP四层参考模型。这两个模型在网络中应用最为广泛。
OSI七层参考模型:
OSI(Open System Interconnection)开放系统互连参考模型是国际标准化组织(ISO)
制定的一个用于计算机或通信系统间互联的标准体系。
TCP/IP四层参考模型 TCP/IP参考模型是计算机网络的祖父ARPANET和其后继的因特网使用的参考模型。 应用层 表示层 会话层 应用层 ---------------------------- 传输层 传输层 ----------------------------- 网络层 网络层 --------------------------- 数据链路层 物理层 网络接口层
三,网络通信三要素
1,ip地址:
-网络中设备的标识
2,端口号
-计算机中应用程序的标识,进程标识
3,传输协议
-通信规则: tcp udp
四,ip地址
1,要想让网络中的计算机能够进行通信,必须给每个计算机
指定一个标识号。通过这个标识来指定接收信息的计算机和
发送信息的计算机。在tcp/ip 协议中,这个标识叫做ip地址
2,如何获取和操作ip地址?
-为了方便我们对ip地址的获取和操作,java就提供了一个类:InetAddress
3,ip地址:IP地址(Internet Protocol Address)
-就是给网络上链接的计算机分配的一个32bit地址。按照tcp/ip 规定
ip地址是用二进制标识的。每一ip长32bit。换算成字节就是4个字节。
10100010 01011010 00010001 00010000 这个太长了。我们处理和记忆都步方便。
为了方便记忆和使用,ip地址就被改写成了十进制。中间用点隔开
所以我们看到的是 192.168.2.183 叫做点分十进制表示法。
-ip地址的组成:
ip地址:网络号码+主机地址
-ip地址的分类:
A类:第一段是网络号码,后三段是主机号码
B类:前二段是网络号码,后二段是主机号码
C类:前三段是网络号码,后一段是主机号码
特殊地址:127.0.0.1 回环地址 ping 127.0.0.1
xxx.xxx.xxx.255 广播地址
....
五,InetAddress
1,此类表示Internet协议(IP)地址。
2,需要掌握的方法
static InetAddress getByName(String host)
确定主机名称的IP地址。
String getHostName()
获取此IP地址的主机名。
String getHostAddress()
返回文本显示中的IP地址字符串。
package com.momo.demo;
import java.net.InetAddress;
import java.net.UnknownHostException;
public class Demo2 {
public static void main(String[] args) throws UnknownHostException {
InetAddress address = InetAddress.getLocalHost();
System.out.println(address.getHostName());
System.out.println(address.getHostAddress());
// InetAddress inetAddress = InetAddress.getByName("DESKTOP-GGK0E0U"); InetAddress inetAddress = InetAddress.getByName("192.168.137.1"); System.out.println(inetAddress.getHostName()); System.out.println(inetAddress.getHostAddress()); }
}
六,端口号
1,概述
-物理端口: 网卡口
-逻辑端口:我们讲的是这个
不同进程的标识,各个应用程序的标识
范围:0-65535。 0-1024 基本都被系统使用了。
七, tcp 和 udp
1,udp
-把数据源和目的地封装成一个数据包,不需要建立链接,
每个数据包的大小限制在64k。
因为不需要建立链接,所以速度快,但是不可靠。
2,tcp
-建立链接,形成传输通道。在通道中传递数据。
可以传输大量数据。可靠。
因为需要建立链接,所以效率第。
建立链接需要经过三次握手才能建立链接。
八,Socket
1,概述
-Socket网络套接字,套接字是两台机器之间通讯的端点。
-网络上具有唯一标识的ip地址和端口号组合在一起构成的一个能
唯一识别的标识符套接字。
-socket编程,网络编程,套接字编程
-Socket = ip地址+端口号
2.socket原理
-通信2端都要有Scoket
-网络通信其实就是Socket之间的通信
-数据在2个socket之间通过io流传输
3,UDP协议发送数据
-步骤:
创建发送端Socket对象
创建数据,把数据打包
调用对象方法发送数据包
释放资源
package com.momo.demo;
import java.io.IOException;
import java.net.*;
/*
- UDP协议发送端
- */
public class SendDemo {
public static void main(String[] args) throws IOException {
//创建发送端Socket对象
DatagramSocket ds = new DatagramSocket();
//创建数据,把数据打包
//DatagramPacket(byte[] buf, int length, InetAddress address, int port)
//构造用于发送长度的分组的数据报包 length指定主机上到指定的端口号。
byte[] bys = "hello,妹妹,哥哥来了。".getBytes();
InetAddress address = InetAddress.getByName("DESKTOP-GGK0E0U");
int port = 10010;
DatagramPacket dp = new DatagramPacket(bys,bys.length,address,port);
//调用对象方法发送数据包
ds.send(dp);
//释放资源
ds.close();
}
}
4.UDP协议接收数据
-步骤:
创建接收端Socket对象
创建数据包(接收数据)
调用socket对象的接收方法接收数据
解析数据包,输出
释放资源
package com.momo.demo;
import java.io.IOException;
import java.net.*;
/*
- UDP协议接收端
- */
public class ReceiveDemo {
public static void main(String[] args) throws IOException {
//创建接收端Socket对象
DatagramSocket ds = new DatagramSocket(10010, InetAddress.getByName("DESKTOP-GGK0E0U"));
//创建数据包(接收数据)
byte[] bys = new byte[1024];
DatagramPacket dp = new DatagramPacket(bys,bys.length);
//调用socket对象的接收方法接收数据
ds.receive(dp);//阻塞时
//解析数据包,输出
//获取ip
String address = dp.getAddress().getHostAddress();
//获取端口号
int port = dp.getPort();
//获取数据
byte[] data = dp.getData();
int len = dp.getLength();
String s = new String(data,0,len);
System.out.println(address+":"+port+":"+s);
//释放资源
ds.close();
}
}
5,注意事项: -注意端口号被占用 BindException Address already in use: Cannot bind 6,UDP协议下 常用的类和方法 -在UDP协议下发送端和接收端使用的是同一个Socket对象 但是使用的是不同的构造方法 -DatagramSocket 此类表示用于发送和接收数据报数据包的套接字。 DatagramSocket() 构造数据报套接字并将其绑定到本地主机上的任何可用端口。 DatagramSocket(int port) 构造数据报套接字并将其绑定到本地主机上的指定端口。 DatagramSocket(int port, InetAddress laddr) 创建一个数据报套接字,绑定到指定的本地地址。 void receive(DatagramPacket p) 从此套接字接收数据报包。 void send(DatagramPacket p) 从此套接字发送数据报包。 void close() 关闭此数据报套接字。 -DatagramPacket 该类表示数据报包。 DatagramPacket(byte[] buf, int length) 构造一个 DatagramPacket用于接收长度的数据包 length 。 DatagramPacket(byte[] buf, int length, InetAddress address, int port) 构造用于发送长度的分组的数据报包 length指定主机上到指定的端口号。 byte[] getData() 返回数据缓冲区。 InetAddress getAddress() 返回该数据报发送或接收数据报的计算机的IP地址。 int getLength() 返回要发送的数据的长度或接收到的数据的长度。 int getPort() 返回发送数据报的远程主机上的端口号,或从中接收数据报的端口号。
7,通过键盘输入数据发送,当输入88的时候结束输入
-使用广播地址模拟聊天
package com.momo.demo;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
public class Send {
public static void main(String[] args) throws IOException {
DatagramSocket ds = new DatagramSocket();
//键盘输入
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String s = "";
while ((s=br.readLine())!=null){
System.out.println("默默请输入:");
if("88".equals(s)){
break;
}
byte[] bys = s.getBytes(); DatagramPacket dp = new DatagramPacket(bys,bys.length, InetAddress.getByName("192.168.137.255"),10086); ds.send(dp); } ds.close(); }
}
package com.momo.demo;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class Receive { public static void main(String[] args) throws IOException { 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(); int port = dp.getPort(); String s = new String(dp.getData(),0,dp.getLength()); System.out.println(ip+":"+port+":发送了:"+s); } //其实我们不需要释放资源,接收端应该一直开着等待接收数据。 // ds.close(); } }
package com.momo.demo;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
//多线程改进
public class Demo4 {
public static void main(String[] args) throws SocketException, UnknownHostException {
DatagramSocket sendds = new DatagramSocket();
DatagramSocket receiveds = new DatagramSocket(54321);
SendThread st = new SendThread(sendds); ReceiveThread rt = new ReceiveThread(receiveds); Thread t1 = new Thread(st); Thread t2 = new Thread(rt); t2.start(); t1.start(); }
}
package com.momo.demo;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class SendThread implements Runnable{
private DatagramSocket ds;
public SendThread(DatagramSocket ds){
this.ds = ds;
}
@Override
public void run() {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String s = "";
while ((s = br.readLine()) != null) {
if("88".equals(s)){
break;
}
byte[] bys = s.getBytes();
DatagramPacket dp = new DatagramPacket(bys,bys.length, InetAddress.getByName("192.168.137.255"),54321);
ds.send(dp);
}
}catch (IOException e){
e.printStackTrace();
}finally {
ds.close();
}
}
}
package com.momo.demo;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class ReceiveThread implements Runnable{ private DatagramSocket ds; public ReceiveThread(DatagramSocket ds){ this.ds = ds; } @Override public void run() { try { while (true) { byte[] bys = new byte[1024]; DatagramPacket dp = new DatagramPacket(bys, bys.length); ds.receive(dp); String ip = dp.getAddress().getHostAddress(); int port = dp.getPort(); String s = new String(dp.getData(),0,dp.getLength()); System.out.println(ip+":"+port+":发送了:"+s); } }catch (IOException e){ e.printStackTrace(); } } }
九,tcp
1,在tcp协议下发送端和接收端的Socket对象不是同一个
-发送端(客户端): Socket
-接收端(服务端): ServerSocket
2,tcp原理
-创建发送端和接收端的Socket
-建立链接,成功后会形成传输通道
-通过Soket中的流进行数据传递
-关闭socket
3,tcp协议客户端步骤
-创建客户端Socket,要明确要链接的服务器。
-如果链接成功,就会形成传输通道。在通道中
使用流进行数据读写。
-通过socket对象的方法获取流(输入或输出)
-使用流对象的方法进行输出的传输
-如果数据传输完毕,释放资源
-Socket常用的方法
该类实现客户端套接字(也称为“套接字”)。
Socket(InetAddress address, int port)
创建流套接字并将其连接到指定IP地址的指定端口号。
Socket(String host, int port)
创建流套接字并将其连接到指定主机上的指定端口号。
void close()
关闭此套接字。
OutputStream getOutputStream()
返回此套接字的输出流。
InputStream getInputStream()
返回此套接字的输入流。
package com.momo.demo2;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
//tcp协议发送端
public class ClientDemo {
public static void main(String[] args) throws IOException {
//创建客户端socket,指定要链接的服务端
Socket s = new Socket("192.168.137.1",12345);
//获取输出流,写数据
OutputStream os = s.getOutputStream();
os.write("妹妹,我来了。".getBytes());
//释放资源
s.close();
os.close();
}
}
4,tcp协议服务端步骤
-创建服务端Socket,指定一个端口
-等待客户端链接,如果有客户端链接我,使用accept方法
获取客户端(Socket)链接对象。使用客户端对象获取流和
客户端进行通信。
-使用客户端对象获取流对象,进行读写。
-如果服务完成,关闭客户端,也可以关闭服务端。但是
一般不需要关闭服务端。因为服务端需要一直提供服务。
-ServerSocket
这个类实现了服务器套接字。
ServerSocket(int port)
创建绑定到指定端口的服务器套接字。
Socket accept()
侦听要连接到此套接字并接受它。
package com.momo.demo2;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
//tcp协议服务端
public class ServerDemo {
public static void main(String[] args) throws IOException {
//创建服务端Socket
ServerSocket ss = new ServerSocket(12345);
//调用方法监听客户端链接,一旦有客户端链接,可以获取客户端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();
int port = s.getPort();
System.out.println(ip+":"+port+":发送了:"+str);
s.close(); // ss.close(); }
}
package com.momo.demo2;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
//tcp协议客户端
public class ClientDemo {
public static void main(String[] args) throws IOException {
//创建客户端socket,指定要链接的服务端
Socket s = new Socket("192.168.137.1",12345);
//获取输出流,写数据
OutputStream os = s.getOutputStream();
os.write("妹妹,我来了。".getBytes());
//读取服务端返回来的数据 InputStream is = s.getInputStream(); byte[] bys = new byte[1024]; int len = is.read(bys); String str = new String(bys,0,len); System.out.println(str); //释放资源 s.close(); os.close(); }
}
package com.momo.demo2;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
//tcp协议服务端
public class ServerDemo {
public static void main(String[] args) throws IOException {
//创建服务端Socket
ServerSocket ss = new ServerSocket(12345);
//调用方法监听客户端链接,一旦有客户端链接,可以获取客户端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();
int port = s.getPort();
System.out.println(ip+":"+port+":发送了:"+str);
//服务端给客户端返回信息 OutputStream os = s.getOutputStream(); os.write("我收到了".getBytes()); s.close(); // ss.close(); }
}
5,练习
-客户端通过键盘给服务端发送数据,服务端输出到控制台
-客户端通过键盘给服务端发送数据,服务端输出到文件中
-客户端读取文本文件中的数据发送,服务端输出到文件中(控制台)
-模拟上传图片
-把服务端代码用线程封装,模拟一个可以同时接收多人上传文件的服务器
package com.momo.demo2;
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
//客户端通过键盘给服务端发送数据,服务端输出到控制台
public class Client {
public static void main(String[] args) throws IOException {
Socket s = new Socket(InetAddress.getByName("192.168.137.1"),23456);
//封装键盘输入
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//把通道中的流包装一下
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
String str = "";
while ((str=br.readLine())!=null){
if("88".equals(str)){
break;
}
bw.write(str);
bw.newLine();
bw.flush();
}
// bw.close();
//br.close();
s.close();
}
}
package com.momo.demo2;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
public class Server { public static void main(String[] args) throws IOException { ServerSocket ss = new ServerSocket(23456); Socket s = ss.accept(); //包装流 BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream())); String str = ""; while ((str=br.readLine())!=null){ System.out.println(str); } s.close(); // br.close(); // ss.close(); } }
标签:java,String,编程,字符集,网络,import,new,public,Socket From: https://blog.51cto.com/u_16230968/7501906