Java中另一个重要技术就是网络编程了,为了更好的学习web方向的知识,有必要对java之网络编程好好学习,本文将围绕网络编程技术进行分析。
常见的网络协议:UDP、TCP
UDP
1、 将数据源和目的封装为数据包,不需要建立连接
2、每个数据包大小在64K内
3、因为面向无连接,所以不可靠(丢失数据)
4、不需要连接,速度快
常见的UDP:聊天、视频会议、桌面共享等等。
TCP
1、 建立连接,形成传输数据的通道
2、在连接中进行大量数据的传输
3、通过三次握手完成连接,是可靠协议
4、必须建立连接,效率会相对较低
Socket
Socket就是为网络服务的一种机制,通信两段都有socket,网络通信其实就是socket间的通信。数据自练个socket间通过IO传输。
UDP建立连接步骤
需求:通过UDP传输方式,将一段文字发送出去,另一端进行接受并打印
思路:
发送端:
1、建立UDP socket服务
2、提供数据,将数据封装到数据包中
3、通过socket服务,将数据包发送出去
4、关闭资源
接受端:
1、定义UDP socket服务,通常会监听一个端口,方便与明确该应用程序处理的对象。
2、定义一个数据包,以便于存储接收到数据,数据包对象中提供了更多操作接收数据处理的方法
3、通过socket服务的receive方法,将接收到的数据包存于已定义的数据包中。
4、通过数据对象特有的功能将这些不同的数据取出,并进行后续的处理
5、关闭资源
具体步骤:
发送端:
1、创建UDP服务,通过DatagramSocket对象
DatagramSocket ds =new DatagramSocket();
2、确定数据并封装成数据包
DatagramPacket dp=new DatagramPacket(buf,buf.length,InetAdress,port)
3、通过socket服务,将已经封包的数据进行发送
ds.senf(dp)
4、关闭资源
ds.close();
接收端:
1、创建UDP socket,建立端点(指明监听的端口)
DatagramSocket ds =new DatagramSocket(100010);
2、 定义数据包用于存储接受进来的数据
Byte []by=new byte[1024];
DatagramPacket dp=new DatagramPacket(by,by.length);
3、通过服务的receive方法接受数据,并存于到已定义的数据包中
ds.receive(dp);
4、通过数据包的特有方法去除取出其中的数据
String s=new String(dp.getData());
5、关闭资源
ds.close();
TCP建立连接步骤
需求:建立TCP链接,并传输一段数据到服务器,服务器接收数据并打印该数据
客户端
1、 建立服务端点,指明主机名以及端口号
Socket s=new Socket("127.0.0.1",10010);
2、读取客户端要传送的数据
byte []by="TCP I am coming".getBytes();
3、通过socket输出流将数据发给服务器
OutputStream out=s.getOutputStream();
out.wirte(by);
5、关闭资源
s.close();
服务端:
1、 建立服务端并指明监听端口
ServerSocket ss=new ServerSocker=t(10010);
2、开启服务,并接受数据
Scoket s=ss.accept();
3、读取接受到的数据,并封装成包(本例只是打印)
InputStream in=s.getInputStream();
int len=0;
byte by[]=new byte[1024];
len=in.read(by);
System.out.println(new String(by,0,len));
4、关闭资源
s.close();
案例分析:
需求:编写一个UDP聊天程序:
分析:
有接受数据的部分,和发数据的部分,这两部分需要同时执行,这就需要用到多线程了
发送端:
/*
* 编写一个聊天程序:
* 分析:
* 有接受数据的部分,和发数据的部分,这两部分需要同时执行,这就需要用到多线程了
* */
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Scanner;
/*
* 发送端
*
* */
public class UDP_Send_03 implements Runnable{
private DatagramSocket ds;
UDP_Send_03(DatagramSocket ds){
this.ds=ds;
}
public void run() {
try {
ds=new DatagramSocket();
Scanner sc=new Scanner(System.in);
String line;
while((line=sc.nextLine())!=null){
if("886".equals(line))
break;
byte by[]=line.getBytes();
DatagramPacket dp=new DatagramPacket(by,by.length,InetAddress.getByName("127.0.0.1"),10110);
ds.send(dp);
}
} catch (SocketException e) {
e.printStackTrace();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} }
接收端:
import java.io.IOException;
import java.net.*; /*
* 编写一个聊天程序:
*
* 接受端
* */
public class UDP_Rec_03 implements Runnable {
private DatagramSocket ds;
UDP_Rec_03(DatagramSocket ds){
this.ds=ds;
}
public void run() {
try {
ds=new DatagramSocket(10110); while(true){
byte by[]=new byte[1024]; DatagramPacket dp=new DatagramPacket(by,by.length);
ds.receive(dp);
String data=new String(dp.getData(),0,dp.getLength()); System.out.println(data);
}
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} }
//通过多线程的方式同时开启两个服务,这样就可以模拟聊天软件的环境进行交流了
public static void main(String[] args) throws SocketException {
DatagramSocket ds=new DatagramSocket();
UDP_Rec_03 rec=new UDP_Rec_03(ds);
UDP_Send_03 send=new UDP_Send_03(ds);
new Thread(rec).start();
new Thread(send).start(); }
}
案例2:编写一个基于TCP的程序,完成客户端向服务器发送一段文字,服务器接收到后返回一段文字,客户端打印反馈的信息
客户端:
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException; /*
* 文件复制,需求:将客户端的文件发到服务端,进行磁盘存储
* */
public class CopyOfTCP_cli_04优化版 {
public static void main(String[] args) throws UnknownHostException, IOException {
Socket s=new Socket("127.0.0.1",10011);
//获取输出流,将字节转化为字符,可以一次写一行数据
PrintWriter pw=new PrintWriter(s.getOutputStream(),true);
//读取文件,用到了带缓冲的Reader,可以一次读取一行
BufferedReader br=new BufferedReader(new FileReader("E:\\a.txt"));
String line=null;
while((line=br.readLine())!=null){
pw.println(line);
}
//文件发送完成,需要发送一个结束标记 要格外注意
pw.println("over"); //或者使用s.shutdownOutput(); BufferedReader in=new BufferedReader(new InputStreamReader(s.getInputStream())); while((line=in.readLine())!=null)
{
System.out.println("服务器说:"+line);
}
br.close();
in.close();
pw.close();
s.close(); }
}
服务端:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket; public class CopyOfTCP_ser_04优化版 {
public static void main(String[] args) throws IOException {
ServerSocket ss=new ServerSocket(10011); Socket s=ss.accept();
//接受客户端发送的文件,用到了缓冲,并且将字节流转化为了字符流
BufferedReader br =new BufferedReader(new InputStreamReader(s.getInputStream()));
//向文件中写数据,用到了缓冲,可以写一行
BufferedWriter bo=new BufferedWriter(new FileWriter("E:\\BB.txt"));
//向客户端写数据,用到了将字节流包装为Printwriter 从而可以将字节转化为字符串处理
PrintWriter out=new PrintWriter(s.getOutputStream(),true);
String line=null;
while((line=br.readLine())!=null){
if("over".equals(line))
break;
bo.write(line);
bo.newLine();
bo.flush();
}
out.println("文件收到");
out.flush();
s.close(); }
}