Java网络编程
网络编程的实质就是两个(或多个)设备(例如计算机)之间的数据传输。
基于TCP协议的编程,上传视频:
package demo01;
import java.io.*;
import java.net.Socket;
//客户端发发送信息
/*1.先从本地文件读取视频
* 2.建立网络连接
* 3.将文件流发到网络流里面*/
public class Client {
public static void main(String[] args) throws IOException {
// File file =new File()
File file =new File("E:\\java上传文件\\视频文件1.mp4");
FileInputStream fos = new FileInputStream(file);
//Socket的构造一定得要ip地址跟端口号,不然不知道发给谁
Socket socket =new Socket("localhost",6666);
OutputStream os = socket.getOutputStream();
int leng =-1;
byte b[] = new byte[1024 * 8];
while ((leng = fos.read(b)) != -1) {
os.write(b,0,leng);
}
System.out.println("发送完成");
socket.shutdownOutput();
os.close();
}
}
服务器:
package demo01;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
//服务器的创建及使用
public class Service {
public static void main(String[] args) throws IOException {
//基于Tcp协议的面向连接的传输
//1.建立网络连接,好比网线,服务器使用Server 监听
ServerSocket serverSocket = new ServerSocket(6666);
//在服务器中建立文件夹,保存客户端文件
File file = new File("E:\\java上传文件");
if (!file.exists()) {
file.mkdirs();
}
File file1 = new File(file, "视频文件1.mp4");
//建立从网线输出到文件的流对象
FileOutputStream fileOutputStream = new FileOutputStream(file1);
//监听到一个客户端往服务器发消息,建立连接。
Socket socket = serverSocket.accept();
//利用socket进行流的传输
InputStream is = socket.getInputStream();
int leng =-1;
byte b[] = new byte[1024*8];
while ((leng = is.read(b)) != -1) {
fileOutputStream.write(b,0,leng);
}
System.out.println("接收已完成!");
socket.shutdownInput();
fileOutputStream.close();
}
}
基于TCP的编程的步骤:
1.先在服务器上建立一个Socket网络连接对象
构造参数是地址名+端口号(运行程序)
2. 建立网络流对象 socket.getInputStream
3.向该流写入数据,数据形式可以以字节数组形式写入
4.最后关闭资源先写shutdown关闭网络
5.注意shutdown先写,再写close 它是避免客户一直等待数据闯过来,预防死锁。
InetAddress类的使用
没有构造方法,那么如何使类提供的功能呢?
要掌握的功能
获取任意主机:getByName
主机名:getHostName
主机Ip地址:getHostAddress
InetAddress是直接类名.方法名创建对象
UDP
将数据源和目的封装成数据包中,不需要建立连接;每个数据报的大小在限制在64k;因无连接,是不可靠协议;不需要建立连接,速度快
TCP
建立连接,形成传输数据的通道;在连接中进行大数据量传输;通过三次握手完成连接,是可靠协议;必须建立连接,效率会稍低
Socket
Socket套接字:
网络上具有唯一标识的IP地址和端口号组合在一起才能构成唯一能识别的标识符套接字。
Socket原理机制:
通信的两端都有Socket。
网络通信其实就是Socket间的通信。
数据在两个Socket间通过IO传输。
1.Socket客户机需要写ip和端口号,服务器只要端口号
Tcp客户端思路:
1:建立客户端的Socket服务,并明确要连接的服务器。
2:如果连接建立成功,就表明,已经建立了数据传输的通道.就可以在该通道通过IO进行数据的读取和写入.该通道称为Socket流,Socket流中既有读取流,也有写入流.
3:通过Socket对象的方法,可以获取这两个流
4:通过流的对象可以对数据进行传输
5:如果传输数据完毕,关闭资源
TCP传输-服务器端思路:
1:建立服务器端的socket服务,需要一个端口
2:服务端没有直接流的操作,而是通过accept方法获取客户端对象,在通过获取到的客户端对象的流和客户端进行通信
3:通过客户端的获取流对象的方法,读取数据或者写入数据
4:如果服务完成,需要关闭客户端,然后关闭服务器,但是,一般会关闭客户端,不会关闭服务器,因为服务端是一直提供服务的
UDP协议思路:客户机
1.由于是使用无连接的所以使用DatagramSocket
2.创建一个数据包 DatagramPacket
3如果发送数据包,就把相关地址,端口号写在数据包中
4.最后在DatagramSocket上 send
服务器:
1.创建无线网络DatagramSocket 这次需要有一个端口号的参数!!!!
2.定义一个缓冲数组,new一个数据包传入数组和数组长度接收。
3.最重要的就是在该网络下,receive!!!记得先收包
4.定义一个数组接收该包裹的分解
4.最后进行拆包
UDP的客户端:
package demo06;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;
public class Client {
//基于UDP的网络交互聊天
public static void main(String[] args) throws IOException {
//创建无限网络
DatagramSocket ds =new DatagramSocket();
while (true){
Scanner input = new Scanner(System.in);
String s = input.next();
InetAddress inetAddress = InetAddress.getByName("10.10.28.194");
DatagramPacket dp = new DatagramPacket(s.getBytes(),0,s.getBytes().length,inetAddress,8990);
ds.send(dp);
//接收一个新包裹
/*1.定义一个缓冲区接收包裹即数组的形式tBytes(), s.getBytes().length, inetAddress, 6789);
//将包裹发送
2、定义一个新包裹装这些缓冲区的数据
3.拆解包裹,拿数据
* */
byte b[] =new byte[1024];
DatagramPacket dp1 = new DatagramPacket(b, b.length);
ds.receive(dp1);
byte by[] = dp1.getData();
System.out.println(new String(by,0,by.length));
}
//创建一个数据包
}
}
UDP的服务器:
package demo06;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketAddress;
import java.util.Scanner;
public class Service {
public static void main(String[] args) throws IOException {
//开wifi
DatagramSocket ds = new DatagramSocket(6666);//指定端口号
//接收包裹
while (true){
byte b[] =new byte[1024];
DatagramPacket dp = new DatagramPacket(b,b.length);
ds.receive(dp);
//拆包
byte by[] = dp.getData();
System.out.println(new String(by, 0, by.length));
//进行回复
SocketAddress sa = dp.getSocketAddress();
//新建一个包裹
Scanner input = new Scanner(System.in);
String s =input.next();
DatagramPacket dp1 = new DatagramPacket(s.getBytes(),0,s.getBytes().length,sa);
//在wifi下发送包裹
ds.send(dp1);
}
}
}
在服务器中发送信息给客户端,是需要地址的,使用上一次收到包裹的地址即可,使用SocketAddress 不要InteAddress
多线程的网络中,在服务器的监听对象中接收多个客户端,需要使用while循环不停的accept返回Socket对象,建立网络连接