1. 知识点
ip地址在java中的实现包:InetAddress
ip地址作用:确定唯一一台计算机
127.0.0.1:本机,等同于localhost
ip地址分类:
- ipv4:4个字节组成,0-255,一共42亿个
- ipv6:16个字节组成,2个字节一组,不同组使用:隔开,(4个16进制数为一组,一共8组)
端口:应用程序的入口,不同的进程有不同的端口号,TCP和UDP端口号都有65535个。
公有端口:0-1023
- HTTP:80
- HTTPS:443
- FTP:21
- Telent:23
普通端口:1024-49151
- Tomcat:8080
- MySQL:3306
- Oracle:1521
动态端口:49152-65535,程序动态运行时的临时端口
InetAddress:方法
- 获取IP地址实例:InetAddress.getByName()
- 获取实例里的信息:
- getHostAddress:IP地址
- getHostName:域名(如果在hosts里配置了ip地址映射),或者主机名
CMD查看端口状态:netstat -ano
* ESTABLISHED:已经建立连接的
* LISTENING:监听状态(就是启用了该端口,但是还没有应用连接)
CMD查看进程:tasklist|findstr "8696"
,查看8696端口的进程
ip地址+端口类:InetSocketAddress
,用于实现IP套接字的类,用于socket通信
2. 通信协议
TCP/IP协议簇:
- TCP:用户传输协议
- UDP:数据报协议
TCP协议:稳定,三次握手四次挥手,客户端和服务端,传输完成就需要释放连接,效率低
UDP协议:不稳定
3. TCP编程Demo
简易的单方发送数据的客户端和服务端:
// 客户端
public class Demo01 {
public static void main(String[] args) throws IOException {
// Client
Socket client = new Socket("localhost", 1890);
OutputStream outputStream = client.getOutputStream();
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
Scanner sc = new Scanner(System.in);
String s="";
while(!"bye".equals(s)){
System.out.print("in:");
s = sc.nextLine();
bufferedWriter.write(s);
bufferedWriter.newLine();
bufferedWriter.flush();
}
bufferedWriter.close();
client.close();
}
}
// 服务端
public class Demo02 {
public static void main(String[] args) throws IOException {
// Server
ServerSocket server = new ServerSocket(1890);
Socket accept = server.accept();
InputStream inputStream = accept.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while((line=bufferedReader.readLine())!=null){
System.out.println("out:"+line);
}
bufferedReader.close();
accept.close();
server.close();
}
}
先启动服务端,然后客户端可以对其发送数据,当客户端输入bye时,自动退出,同时服务端也退出
简易的文件上传功能:特别注意,如果一方读取另一方的输入,则输入的一方不需要输入时,需要调用shutdownXXX方法来告诉另一方读取结束了!!
public class Demo03 {
public static void main(String[] args) throws IOException {
// 客户端
Socket socket = new Socket("127.0.0.1", 1089);
OutputStream outputStream = socket.getOutputStream();
FileInputStream fileInputStream = new FileInputStream("a.html");
byte[] b = new byte[1024];
int a;
while((a=fileInputStream.read(b))!=-1){
outputStream.write(b,0,a);
}
// 如果此处不关闭,则服务器一直处于读取客户端输出流状态!!
socket.shutdownOutput();
InputStream inputStream = socket.getInputStream();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
while ((a=inputStream.read(b))!=-1){
bos.write(b,0,a);
}
System.out.println(bos.toString());
bos.close();
inputStream.close();
outputStream.close();
fileInputStream.close();
socket.close();
}
}
public class Demo04 {
public static void main(String[] args) throws IOException {
// 服务器
ServerSocket serverSocket = new ServerSocket(1089);
Socket accept = serverSocket.accept();
InputStream inputStream = accept.getInputStream();
FileOutputStream fileOutputStream = new FileOutputStream("b.html");
byte[] b = new byte[1024];
int a;
while((a=inputStream.read(b))!=-1){
fileOutputStream.write(b,0,a);
}
OutputStream outputStream = accept.getOutputStream();
outputStream.write("我搞定了".getBytes());
outputStream.close();
fileOutputStream.close();
inputStream.close();
accept.close();
serverSocket.close();
}
}
tomcat日志输出乱码:去根目录下找config目录里的log配置文件,改里面的log编码配置为gbk(Windows)
4. UDP编程Demo
这个demo功能:接受方接收发送方发送的数据,并给予回复,发送方接收回复
public class UdpTest {
public static void main(String[] args) {
DatagramSocket datagramSocket=null;
try {
// 建立包通道
datagramSocket = new DatagramSocket(1099);
// 新建数据报
byte[] b="你好baby!".getBytes();
DatagramPacket datagramPacket = new DatagramPacket(b, b.length, InetAddress.getByName("127.0.0.1"), 1090);
// 发送数据报
datagramSocket.send(datagramPacket);
// **扩展** //
// 查看回复
byte[] data = new byte[1024];
datagramPacket = new DatagramPacket(data,data.length,InetAddress.getByName("127.0.0.1"), 1090);
datagramSocket.receive(datagramPacket);
b = datagramPacket.getData();
System.out.println(new String(b));
} catch (SocketException | UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
datagramSocket.close();
}
}
}
class UdpTest2 {
public static void main(String[] args) {
DatagramSocket datagramSocket = null;
try{
// 建立通道
datagramSocket = new DatagramSocket(1090);
// 接收数据报
byte[] b = new byte[1024];
DatagramPacket datagramPacket = new DatagramPacket(b, b.length);
datagramSocket.receive(datagramPacket);
// 查看内容
byte[] data = datagramPacket.getData();
System.out.println(new String(data));
// **扩展** //
// 回复消息
b="我已收到".getBytes();
datagramPacket = new DatagramPacket(b, b.length, InetAddress.getByName("127.0.0.1"), 1099);
datagramSocket.send(datagramPacket);
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
datagramSocket.close();
}
}
}
注意:InetAddress可以使用InetSocketAddress来代替,可以直接设置ip和端口
5. URL
URL类:统一资源定位
输出:
从网络上通过URL下载资源
URL url = new URL("地址");
HttpURLConnection urlc = (HttpURLConnection)url.openConnection();
InputStream in = urlC.getInputStream();
FileOutputStream fos = new FileOutputStream("a.txt");
//流操作
fos.close();
in.close();
urlc.disconnect(); // 断开连接