网络编程
定义
计算机网络
是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统。
网络编程
用来实现网络互连不同计算机上运行的程序可以进行数据交换
IP地址
每个设备在网络中的唯一标识
每台网络终端在网络中都有一个独立的地址,我们在网络中传输数据就是使用这个地址
ipconfig:查看本机ip
ping:测试连接
端口号
每个程序在设备上的唯一标识
每个网络程序都需要绑定一个端口号,传输数据除了确定发到哪台机器上,还要明确发到哪个程序
端口号范围从0-65535
编写网络应用需要绑定一个端口号,尽量使用1024以上的,1024以上的基本上都被系统程序占用了。
协议
为计算机网络中进行数据交换而建立的规则,标准或约定的集合。
UDP
面向无连接,数据不安全,速度快。不区分客户端和服务端
TCP
面向连接(三次握手),数据安全,速度略低。分为客户端和服务器端。
三次握手:客户端先向服务器短发送请求,服务器端响应请求,客户端确认信息。
Socket通信
定义
网络上具有唯一标识的Ip地址和端口号组合在一起才能构成唯一识别标识符套接字
通信两端都有Socket
网络通信其实就是Socket间的通信
数据在两个Socket间通过IO流传输
Socket在应用程序中创建,通过一定绑定机制与驱动程序建立关系,告诉自己所对应的Ip和Port
UDP传输
1.发送Send
创建DatagramSocket, 随机端口号
创建DatagramPacket, 指定数据, 长度, 地址, 端口
使用DatagramSocket发送DatagramPacket
关闭DatagramSocket
2.接收Receive
创建DatagramSocket, 指定端口号
创建DatagramPacket, 指定数组, 长度
使用DatagramSocket接收DatagramPacket
关闭DatagramSocket
从DatagramPacket中获取数据
3.接收方获取ip和端口号
String ip = packet.getAddress().getHostAddress();
int port = packet.getPort();
TCP协议
定义
客户端和服务器间的交流, 客户端发送信息,服务器接收到,并返回信息
长连接
使用步骤
客户端
创建Socket连接服务端(指定ip地址,端口号)通过ip地址找对应的服务器
调用Socket的getInputStream()和getOutputStream()方法获取和服务端相连的IO流
输入流可以读取服务端输出流写出的数据
输出流可以写出数据到服务端的输入流
服务端
创建ServerSocket(需要指定端口号)
调用ServerSocket的accept()方法接收一个客户端请求,得到一个Socket
调用Socket的getInputStream()和getOutputStream()方法获取和客户端相连的IO流
输入流可以读取客户端输出流写出的数据
输出流可以写出数据到客户端的输入流
演示
客户端
publicstaticvoidmain(String[]args)throwsException{
Socketsocket=newSocket("127.0.0.1",6666);
//发送信息
OutputStreamstream=socket.getOutputStream();
Stringstr="我很中意你呀";
stream.write(str.getBytes());
//接收返回的信息
InputStreamis=socket.getInputStream();
byte[]bs=newbyte[1024];
intlen;
len=is.read(bs);
System.out.println(newString(bs,0,len));
socket.close();
}
服务端
publicstaticvoidmain(String[]args)throwsException{
ServerSocketserver=newServerSocket(6666);
Socketsocket=server.accept();
//接收信息
InputStreamis=socket.getInputStream();
byte[]bs=newbyte[1024];
intlen;
len=is.read(bs);
System.out.println(newString(bs,0,len));
//返回信息
OutputStreamstream=socket.getOutputStream();
Stringstr="哎呀, 知道了";
stream.write(str.getBytes());
socket.close();
}
TCP传输优化
客户端
publicstaticvoidmain(String[]args)throwsException{
Socketsocket=newSocket("127.0.0.1",6666);
//接收信息
InputStreamis=socket.getInputStream();
BufferedReaderbr=newBufferedReader(newInputStreamReader(is));
//发送信息
OutputStreamstream=socket.getOutputStream();
BufferedWriterbw=newBufferedWriter(newOutputStreamWriter(stream));
BufferedReadersca=newBufferedReader(newInputStreamReader(System.in));
Stringstr;
while(true){
str=sca.readLine();
if("结束".equals(str)) {
break;
}
bw.write(str);
bw.newLine();
bw.flush();
//接收返回的信息
str=br.readLine();
System.out.println(str);
}
socket.close();
}
服务端
publicstaticvoidmain(String[]args)throwsException{
ServerSocketserver=newServerSocket(6666);
Socketsocket=server.accept();
//接收信息
InputStreamis=socket.getInputStream();
BufferedReaderbr=newBufferedReader(newInputStreamReader(is));
//发送信息
OutputStreamstream=socket.getOutputStream();
BufferedWriterbw=newBufferedWriter(newOutputStreamWriter(stream));
BufferedReadersca=newBufferedReader(newInputStreamReader(System.in));
Stringstr;
while(true){
str=br.readLine();
System.out.println(str);
str=sca.readLine();
if("结束".equals(str))
break;
bw.write(str);
bw.newLine();
bw.flush();
}
socket.close();
}
六. 多线程服务器
定义
每当一个请求过来,服务器就会产生一个Socket连接, 为了避免前面的socket阻碍后面的socket运行, 我们必须创建一个新的线程来出来请求
演示
publicstaticvoidmain(String[]args)throwsException{
ServerSocketserver=newServerSocket(9999); //创建服务器
while(true) {
Socketsocket=server.accept(); //接受客户端的请求
//创建一个线程来处理请求
newThread() {
publicvoidrun() {
try{
BufferedReaderbr=newBufferedReader(newInputStreamReader(socket.getInputStream()));
PrintStreamps=newPrintStream(socket.getOutputStream());
ps.println("欢迎咨询千锋互联");
System.out.println(br.readLine());
ps.println("报满了,请报下一期吧");
System.out.println(br.readLine());
socket.close();
}catch(IOExceptione) {
e.printStackTrace();
}
}
}.start();
}
}
六. 文件上传
定义
其实就是通过流从本地文件中读取数据,通过网络传输到服务器
服务器在接受到数据之后再存储到本地
演示
客户端
publicstaticvoidmain(String[]args)throwsException{
//1.和服务器建立连接
Socketsocket=newSocket("127.0.0.1",9999);
//2.获取输出流,往服务器写数据
//BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
OutputStreamos=socket.getOutputStream();
//3.获取输入流,获取服务器发送过来的数据
BufferedReaderbr=newBufferedReader(newInputStreamReader(socket.getInputStream()));
FileInputStreamfis=newFileInputStream("d:\\骑在银龙的背上.mp3");
byte[]bs=newbyte[1024];
intlen;
while((len=fis.read(bs))!=-1) {
os.write(bs,0,len);
}
socket.shutdownOutputStream();
Stringstr=br.readLine();
if("200".equals(str))
System.out.println("文件上传成功");
else
System.out.println("文件上传失败");
socket.close();
}
服务端
publicstaticvoidmain(String[]args)throwsException{
//服务端必须先启动
ServerSocketserverSocket=newServerSocket(9999);
//1.和客户端建立连接(被动)
Socketsocket=serverSocket.accept();
//2.获取输入流,获取从客户端发送过来的数据
InputStreamis=socket.getInputStream();
//3.获取输出流,往客户端写数据
BufferedWriterbw=newBufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
FileOutputStreamfos=newFileOutputStream("d:\\音乐.mp3");
byte[]bs=newbyte[1024];
inti;
while((i=is.read(bs))!=-1){
fos.write(bs,0,i);
}
//写一个200回去表示成功
bw.write("200");
bw.newLine();
bw.flush();
fos.close();
socket.close();
}
总结:
网络传输的概述
ip : 通过ip可以找到网络中的一台机器
port : 通过端口号可以找到电脑中某个程序
ip+port : 一个套接字
udp : 快, 不安全 面向无连接
tcp : 慢 ,安全 面向有链接
UDP 编码
DatagramSocket
DatagramPacket
DatagramPacket包裹着ip地址,端口号, 数据, DatagramSocket发送包裹
接收端和发送端时平等的
TCP编程
Socket
ServerSocket
ServerSocket可以接收多个Socket , 每接收一个客户端连接, 就会创建一个Socket 和客户端通信
TCP的最大优点 : 两端是由一个通道连接, 可以随意传输数据, 不会受数据量大小的限制
服务端一般和多线程配合使用
查阅资料, 思考TCP传输的缺点和解决办法?