JAVA基础之网络通信协议--TCP与UDP
个人理解:
了解区分udp与tcp的不同,正常情况都是两者结合的使用模式!为了更好的传输,经常会开多线程进行传输的!
一、网络通信协议:
1、tcp/ip协议:
四层:应用层、传输层、网络层和链路层:
链路层:链路层是用于定义物理传输通道,通常是对某些网络连接设备的驱动协议,例如针对光纤、网线提供的驱动。
网络层:网络层是整个tcp/ip协议的核心,它主要用于将传输的数据进行分组,将分组数据发送到目标计算机或者网络。
传输层:主要使网络程序进行通信,在进行网络通信时,可以采用tcp协议,也可以采用udp协议。
应用层:主要负责应用程序的协议,例如http协议、ftp协议等。
2、ip地址和端口号:
①、ip地址,它可以唯一标识一台计算机:
以前为ipv4,现在是ipv6的16个字节表示地址。
②、端口号:两个字节:0-65535。一般为1024以上的端口号。
3、inetaddress类:
import java.net.inetaddress; import java.net.unknownhostexception; public class demo01 { public static void main(string[] args) throws unknownhostexception { inetaddress inet=inetaddress.getbyname("192.168.1.163");//里面是自己的ip地址 //从对象中获取ip地址 system.out.println(inet.gethostaddress()); //获取主机名 system.out.println(inet.gethostname()); //获取本地主机ip对象 inetaddress inet2=inetaddress.getlocalhost(); system.out.println(inet2.gethostaddress()); system.out.println(inet2.gethostname()); } }
二、udp与tcp协议:
1、udp协议:
user datagram protocol 用户数据报协议--无连接的通信协议:不能保证数据的完整性,随缘!!!64k以内。
2、tcp协议:
transmission control protocol 传输控制协议---面向连接的通信协议:
在传输数据前先在发送端和接收端建立逻辑连接,然后再传输数据。
在tcp连接中必须要明确客户端与服务器端,由客户端向服务端发出连接请求,每次连接的创建都需要经过“三次握手”。第一次握手,客户端向服务器端发出连接请求,等待服务器确认,第二次握手,服务器端向客户端回送一个响应,通知客户端收到了连接请求,第三次握手,客户端再次向服务器端发送确认信息,确认连接。
三、udp通讯:
1、datagrampacket:数据打包类:
用于封装udp通信中发送或者接收的数据。
2、datagramsocket:“码头”:可以发送和接收datagrampacket数据包
import java.io.ioexception; import java.net.datagrampacket; import java.net.datagramsocket; import java.net.inetaddress; import java.net.socketexception; import java.net.unknownhostexception; //发送端 public class udpsend { public static void main(string[] args) throws ioexception { //封装数据 byte[ ] bytes="你好udp".getbytes(); //封装ip地址 inetaddress inet=inetaddress.getbyname("127.0.0.1"); //1。创建数据打包对象,封装要发送的数据、长度、接收端的ip地址和端口号 datagrampacket dp=new datagrampacket(bytes,bytes.length,inet,6000); //2.创建datagreamsocket对象(快递公司) datagramsocket ds=new datagramsocket(); //3.发送数据包 ds.send(dp); //释放资源 ds.close(); } }
import java.io.ioexception; import java.net.datagrampacket; import java.net.datagramsocket; import java.net.socketexception; //接收端 public class udpreceive { public static void main(string[] args) throws ioexception { //创建datagramsocket对象,明确端口号 datagramsocket ds=new datagramsocket(6000); //2.创建字节数组负责接收发来的数据 byte [] bytes=new byte[1024]; //3.创建数据拆包对象 datagrampacket dp=new datagrampacket(bytes,bytes.length); //4.接收数据包 ds.receive(dp); //5.拆包 //获取接收的数据长度 int length=dp.getlength(); //获取发送端的ip地址 string ip=dp.getaddress().gethostaddress(); //获取发送端的端口号 int port =dp.getport(); system.out.println("ip地址为:"+ip+"端口号为:"+port+"发送的内容为:"+new string(bytes,0,length)); } }
四、tcp通信:
1、serversocket类:服务器端;socket类:客户端。
//服务器端 public class tcpserver { public static void main(string[] args) throws ioexception { //1.创建服务器对象serversocket,明确端口号 serversocket server=new serversocket(8888); //2.调用accept方法,跟客户端创建连接,并获取连接的客户端对象 socket socket=server.accept(); //3.明确目的地 file file=new file("d:\\nihao"); //如果该目录不存在则创建 if(!file.exists()){ file.mkdirs(); } string filename="oracle"+system.currenttimemillis()+".txt"; //明确目的地 fileoutputstream fos=new fileoutputstream(file+file.separator+filename); //明确数据源 inputstream in=socket.getinputstream(); //开始复制 int len=0; byte[] bytes=new byte[1024]; while((len=in.read(bytes))!=-1){ fos.write(bytes,0,len); } //回复客户端 //获取字节输出流 ,回复客户端 outputstream out =socket.getoutputstream(); out.write("上传成功".getbytes()); //释放资源 fos.close(); server.close(); } }
//客户端 public class tcpclient { public static void main(string[] args) throws unknownhostexception, ioexception { //1.创建socket对象,明确要连接的服务器地址和端口号 socket socket =new socket("127.0.0.1",8888); //2.明确数据源 fileinputstream fis=new fileinputstream("d:\\java\\a.txt"); //3.从socke对象中获取字节输出流,准备把读的文件字节写给服务器 outputstream out=socket.getoutputstream(); //4.开始复制 int len=0; byte[] bytes=new byte[1024]; while((len=fis.read(bytes))!=-1){ out.write(bytes,0,len); } //结束输出流,告诉服务器结束了,不要读了 socket.shutdownoutput(); //接收服务器的回复 //1.从socket对象中获取字节输入流,接收服务器回复的数据 inputstream in=socket.getinputstream(); len=in.read(bytes); system.out.println(new string(bytes,0,len)); //释放资源 socket.close(); fis.close(); } }
2、多线程传输:
//线程任务对象 public class upload implements runnable { private socket socket; public upload() { }; public upload(socket socket) { this.socket = socket; }; public void run() { fileoutputstream fos = null; try { // 3.明确目的地 file file = new file("d:\\nihao"); // 如果该目录不存在则创建 if (!file.exists()) { file.mkdirs(); } string filename = "oracle" + system.currenttimemillis() + ".txt"; // 明确目的地 fos = new fileoutputstream(file + file.separator + filename); // 明确数据源 inputstream in = socket.getinputstream(); // 开始复制 int len = 0; byte[] bytes = new byte[1024]; while ((len = in.read(bytes)) != -1) { fos.write(bytes, 0, len); } // 回复客户端 // 获取字节输出流 ,回复客户端 outputstream out = socket.getoutputstream(); out.write("上传成功".getbytes()); } catch (ioexception ex) { ex.printstacktrace(); } finally { // 释放资源 try { fos.close(); } catch (ioexception e) { // todo auto-generated catch block e.printstacktrace(); } } } }
public class demo { public static void main(string[] args) throws ioexception { //1.创建服务器对象 serversocket server=new serversocket(8888); while(true){ //创建连接获取客户端对象 socket socket=server.accept(); /*//创建线程(创建线程任务) new thread(new upload(socket)).start();*/ //创建线程任务 upload up=new upload(socket); //创建线程对象 thread thread=new thread(up); //开启线程 thread.start(); } } }