网络编程UDP/TCP协议

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了网络编程UDP/TCP协议相关的知识,希望对你有一定的参考价值。

一、网络编程三要素

IP:网络中设备的标识,不易记忆,可用主机名

端口号:用于标识进程的逻辑地址,不同进程的标识

传输协议:通讯的规则常见协议:TCP,UDP

UDP

把数据打成一个数据包 , 不需要建立连接

数据包的大小有限制不能超过64k

因为无连接,所以属于不可靠协议(可能丢失数据)

因为无连接 ,所以效率高

TCP

需要建立连接,形成连接通道

数据可以使用连接通道直接进行传输,无大小限制

因为有链接,所以属于可靠协议

因为有链接,所以效率低

二、IP以及端口号

1、InetAddress类 —— 表示互联网协议 (IP) 地址

1)此类没有构造方法,创建对象使用方法实现

public static InetAddress getByName(String host) //参数为主机名或者IP的字符串表现形式

2)常用方法

public String getHostAddress() 获取IP

public String getHostName() 获取主机名

2、cmd IP查询

127.0.0.1 本地回环地址 用来做一些本地测试 不走交换机

ping IP地址 用来检测本机是否可以和指定的IP地址的计算机可以进行正常通讯

ipconfig /all  用来查看IP地址

getmac       用来获取mac地址

3、端口号 —— 逻辑端口

用来标示我们的计算机上的进程(正在运行的程序),端口号的有效范围应该是 0-65535,其中0-1024被系统占用或者保留

三、UDP协议

1、DatagramSocket类 —— 此类表示用来发送和接收数据报包的套接字

1)构造方法:

public DatagramSocket()

public DatagramSocket(int port) //参数port 端口号

public DatagramSocket(int port,InetAddress laddr) //参数laddr IP对象

2)常用方法:

public void close()关闭此数据报套接字

public void send(DatagramPacket p) 发送数据报包

public void receive(DatagramPacket p) 接收数据报包

public InetAddress getInetAddress() 返回此套接字连接的地址。如果套接字未连接,则返回 null。

2、DatagramPacket类 —— 此类表示数据报包

1)构造方法:

public DatagramPacket(byte[] buf,int length)

//参数 buf:保存传入数据报的缓冲区 length:一次要读取的长度

public DatagramPacket(byte[] buf,int length,InetAddress address,int port)

//参数 buf:包数据 length:包长度 address:目的IP port:目的端口号

2)解析数据:

public byte[] getData()返回用来接收或发送数据的缓冲区

public int getLength()返回将要发送或接收到的数据的长度

3、使用UDP传输数据

1)客户端:

public class SentDemo {
				public static void main(String[] args) throws IOException {
					InetAddress ip = InetAddress.getByName("接收端ip的字符串变现形式");
					DatagramSocket ds = new DatagramSocket();
					
					byte[] buf = "abc".getBytes();
					DatagramPacket dp = new DatagramPacket(buf, buf.length, ip, 6666);	//端口号不能定义成0-1024
					
					ds.send(dp);
					ds.close();
				}
			}


2)接收端:

public class ReceiveDemo {
				public static void main(String[] args) throws IOException {
					DatagramSocket ds = new DatagramSocket(6666);
					
					byte[] buf = new byte[1024];
					DatagramPacket dp = new DatagramPacket(buf, buf.length);
					
					ds.receive(dp);
					
					System.out.println(new String(dp.getData(),0,dp.getLength()));
					ds.close();
				}
			}


四、TCP协议 —— 使用管道输入输出流传输数据

1、服务器端

1)创建TCP通讯协议服务器端对象

ServerSocket ss = new ServerSocket("端口号");

2)监听客户端

Socket sk = ss.accept();

3)获取管道输入流对象

InputStream is = sk.getInputStream();

4)读取数据 //在使用管道输入流while循环接收数据的时候,不能以-1作为读取完毕的判定条件

//一般循环读取数据时,在客户端调用shutdownOutput()方法,服务端自动跳出循环

byte[] buf = new byte[1024 * 8];

int len = is.read(buf);

System.out.println(new String(buf,0,len));

5)释放资源

ss.close(); //一般服务器不用关闭

2、客户端

1)创建TCP通讯协议客户端对象

Socket sk = new Socket("服务端IP","服务端端口号");

2)获取管道流输出对象

OutputStream os = sk.getOutputStream();

3)写数据

os.write("需要传输的内容".getBytes());

4)释放资源

sk.close();

3、服务端反馈

服务端:

1)创建TCP通讯协议服务器端对象

2)监听客户端

3)获取管道输入流对象

4)读取数据

5)获取管道输出流对象

OutputStream os = sk.getOutputStream();

6)反馈信息

os.write("已收到".getBytes());

客户端:

1)创建TCP通讯协议客户端对象

2)获取管道流输出对象

3)写数据

4)获取管道输入流对象

InputStream is = sk.getInputStream();

4)接收反馈信息

byte[] buf = new byte[1024 * 8];

int len = is.read(buf);

System.out.println(new String(buf,0,len));

5)释放资源

4、shutdownOutput()方法

当客户端发送文件时,发送完毕后调用shutdownOutput()方法,服务端就会收到,停止接收;

sk.shutdownOutput();

5、TCP服务端多线程改进

public class TCPServerDemo {
			public static void main(String[] args) throws IOException {
				ServerSocket ss = new ServerSocket(9527) ;
				//循环监听客户端
				while(true){		
					Socket sk = ss.accept() ;
					// 开启线程
					new Thread(new TCPServerThread(sk)).start() ;
				}
			}
		}
public class TCPServerThread implements Runnable {	
			private Socket sk ;
			public TCPServerThread(Socket sk){
				this.sk = sk ;
			}
			@Override
			public void run() {		
				try {		
					BufferedReader br = new BufferedReader(new InputStreamReader(sk.getInputStream())) ;
					BufferedWriter bw = new BufferedWriter(new FileWriter("a.java")) ;
					// 一次读取一行
					String line = null ;
					while((line = br.readLine()) != null){
						bw.write(line) ;
						bw.newLine() ;
						bw.flush() ;
					}
					try {
						Thread.sleep(100) ;
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					// 给客户端端反馈
					// 获取输出流对象
					OutputStream out = sk.getOutputStream() ;
					out.write("上传文件成功!".getBytes()) ;
					
				} catch (Exception e) {
					e.printStackTrace() ;
				}	
			}
		}


以上是关于网络编程UDP/TCP协议的主要内容,如果未能解决你的问题,请参考以下文章

Linux----网络传输层UDP/TCP

网络通信协议 udp tcp

网络协议+TCP、UDP、TCP/IP、IP、HTTP及其区别联系

传输层UDP/TCP协议

【udp】关于docker 容器网络下使用 UDP 协议无法通讯问题的分析和处理

Linux之socket套接字编程20160704