网络编程通讯的第二要素--网络通信协议(TCP UDP)

网络通信协议

计算机网络中实现通信必须有一些约定,即通信协议。

TCP 和 UDP

TCP
1)使用TCP协议前,须先建立TCP连接,形成传输数据通道
2)传输前,采用“三次握手”方式,是可靠的
3)TCP协议进行通信的两个应用进程:客户端、服务端
4)在连接中可进行大数据量的传输
5)传输完毕,需释放已建立的连接,效率低
UDP
1)将数据、源、目的封装成数据包,不需要建立连接
2)每个数据报的大小限制在64K内
3)因无需连接,故是不可靠的
4)发送数据结束时无需释放资源,速度快

网络套接字(Socket)

1)网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。
2)利用套接字(Socket)开发网络应用程序.
3)通信的两端都要有Socket,是两台机器间通信的端点
4)网络通信其实就是Socket间的通信
5)Socket允许程序把网络连接当成一个流,数据在两个Socket间通过IO传输.也可以说网络编程是IO的扩展,因为在网络传输中也是靠5IO流的操作来完成的。
6)一般主动发起通信的应用程序属客户端,等待通信请求的为服务端
7)启动的时候先启动服务端,在启动客户端

基于Socket的TCP编程

客户端Socket的工作过程包含以下四个基本的步骤
1)创建 Socket:根据指定服务端的 IP 地址或端口号构造 Socket 类对象。
2)打开连接到 Socket 的输入/出流: 使用 getInputStream()方法获得输入流,使用 getOutputStream()方法获得输出流,进行数据传输
3)按照一定的协议对 Socket 进行读/写操作:
4)关闭 Socket:断开客户端到服务器的连接,释放线路
服务端程序的工作过程包含以下四个基本的步骤
调用 ServerSocket(int port) :创建一个服务器端套接字,并绑定到指定端口上。用于监听客户端的请求。
调用 accept():监听连接请求,如果客户端请求连接,则接受连接,返回通信套接字对象。
调用 该Socket类对象的 getOutputStream() 和 getInputStream ():获取输出流和输入流,开始网络数据的发送和接收。
关闭ServerSocket和Socket对象:客户端访问结束,关闭通信套接字。

客户端给服务端发送数据 (亲测可用)

package com.ghl.demo;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;

import org.junit.Test;

/**
 * 网络编程也叫基于Sokect的编程:分为客户端和服务端 
 * 客户端发送数据的步骤:
 * 第一步:创建一个Socket对象,通过构造器指明对方服务器的ip地址和端口号
 *  第二步:通过getOutputStream()方法来发送数据
 * 第三步:具体的输出过程write()
 * 第四步:关闭相应的流
 */
public class TestTCP {
	// 客户端发送数据
	@Test
	public void testClient() {
		Socket socket = null;
		OutputStream os = null;
		try {
			socket = new Socket("127.0.0.1", 8181);// 第一步
			os = socket.getOutputStream();// 第二步
			os.write("我是客户端,我要给服务端的8181端口发送数据".getBytes());// 第三步
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (socket != null && os != null) {
				try {
					socket.close();
					os.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}

	}

	// 服务端:接收数据
	/**
	 * 服务端接收数据的步骤:
	 * 第一步:创建一个ServerSocket对象,通过构造器指明自身的对象(在服务端是ServerSocket)
	 * 第二步:调用accept()的方法,返回一个Socket对象
	 * 第三步:调用Socket对象的getInputStream()获取一个从客户端接收过来的数据
	 * 第四步:对获取的输入流进行操作
	 * 第五步:关闭相应的流
	 */
	@Test
	public void testServer() {
		ServerSocket server = null;
		Socket socket =null;
		InputStream is =null;
		try {
			 server = new ServerSocket(8181);
			 socket = server.accept();
			 is = socket.getInputStream();
			byte[] b=new byte[1024];
			int len;
			while((len=is.read(b))!=-1) {
				String str=new String(b, 0, len);
				System.out.println(str);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			if(server!=null) {
				try {
					server.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if(socket!=null) {
				try {
					socket.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if(is!=null) {
				try {
					is.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}

}

客户端给服务端发送数据,服务端给客户但一个响应,(亲测可用)

package com.ghl.demo;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

import org.junit.Test;

/**
 * 实现功能:客户端给服务端发送数据,服务端告诉客户端我已收到你发的信息
 *
 */
public class TestTCP1 {
	// 客户端发送数据
		@Test
		public void testClient() {
			Socket socket = null;
			OutputStream os = null;
			InputStream is=null;
			try {
				//1.客户端先给服务端发送数据
				socket = new Socket("127.0.0.1", 8181);// 第一步
				os = socket.getOutputStream();// 第二步
				os.write("我是客户端,我要给服务端的8181端口发送数据".getBytes());// 第三步
				//2.客户端告诉服务端我的数据已发送完毕
				socket.shutdownOutput();
			 is=	socket.getInputStream();
			byte[] b=new byte[1024];
			int len;
			while((len=is.read(b))!=-1) {
				String str=new String(b, 0, len);
				System.out.println(str);
			}
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				if (socket != null && os != null) {
					try {
						socket.close();
						os.close();
						is.close();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}

		}

		// 服务端:接收数据
		@Test
		public void testServer() {
			ServerSocket server = null;
			Socket socket =null;
			InputStream is =null;
			OutputStream os = null;
			try {
				 server = new ServerSocket(8181);
				 socket = server.accept();
				 is = socket.getInputStream();
				byte[] b=new byte[1024];
				int len;
				while((len=is.read(b))!=-1) {
					String str=new String(b, 0, len);
					System.out.println(str);
				}
				
				os=socket.getOutputStream();
				os.write("我是服务端,我已接收到客户端发送的数据".getBytes());
			} catch (IOException e) {
				e.printStackTrace();
			}finally {
				if(server!=null) {
					try {
						server.close();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				if(socket!=null) {
					try {
						socket.close();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				if(os!=null) {
					try {
						os.close();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				if(is!=null) {
					try {
						is.close();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		}
}

客户端发一个文件(图片)给服务端,服务端接收存在本地,并返回接收成功给客户端(亲测可用)

package com.ghl.demo;

import static org.hamcrest.CoreMatchers.instanceOf;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

import org.junit.Test;

/**
 * 客户端发一个文件(图片)给服务端,服务端接收存在本地,并返回接收成功给客户端
 *
 */
public class TestTCP2 {
	@Test
	public void testClient() {
		Socket socket = null;
		OutputStream os = null;
		InputStream is = null;
		FileInputStream fis=null;
		try {
			// 1.客户端先给服务端发送数据
			socket = new Socket("127.0.0.1", 8181);
			os = socket.getOutputStream();
			 fis = new FileInputStream(new File("1.jpg"));
			byte[] b1 = new byte[1024];
			int len1;
			while ((len1 = fis.read(b1)) != -1) {
				os.write(b1, 0, len1);
			}
			// 2.客户端告诉服务端我的数据已发送完毕
			socket.shutdownOutput();
			is = socket.getInputStream();
			byte[] b = new byte[1024];
			int len;
			while ((len = is.read(b)) != -1) {
				String str = new String(b, 0, len);
				System.out.println(str);
			}

		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (socket != null && os != null) {
				try {
					socket.close();
					os.close();
					is.close();
					fis.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}

	}

	// 服务端:接收数据
	@Test
	public void testServer() {
		ServerSocket server = null;
		Socket socket = null;
		InputStream is = null;
		OutputStream os = null;
		FileOutputStream fos = null;
		try {
			server = new ServerSocket(8181);
			socket = server.accept();
			is = socket.getInputStream();
			fos = new FileOutputStream(new File("2.jpg"));
			byte[] b = new byte[1024];
			int len;
			while ((len = is.read(b)) != -1) {
			fos.write(b, 0, len);
			}

			os = socket.getOutputStream();
			os.write("我已接收到你发送的数据".getBytes());
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (server != null) {
				try {
					server.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if (socket != null) {
				try {
					socket.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if (os != null) {
				try {
					os.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if (is != null) {
				try {
					is.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if (fos != null) {
				try {
					fos.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
}

UDP网络通信

1)类 DatagramSocket 和 DatagramPacket 实现了基于 UDP 协议网络程序
2)UDP数据报通过数据报套接字 DatagramSocket 发送和接收
3)DatagramPacket 对象封装了UDP数据报,
4)UDP协议中每个数据报都给出了完整的地址信息,因此无须建立发送方和接收方的连接
通信 流 程:
1)DatagramSocket与DatagramPacket
2)建立发送端,接收端
3)建立数据包
4)调用Socket的发送、接收方法
5)关闭Socket

package com.ghl.demo;

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 org.junit.Test;

/**
 * UDP如和以数据报的形式发送数据
 */
public class TestUDP {
	//发送端
	@Test
	public void send() {
		DatagramSocket datagramSocket=null;
		try {
			datagramSocket = new DatagramSocket();
			byte[] buf="我是发送端".getBytes();
			//创建一个数据报,每一个数据报不能大于64k发送ip和端口号,以及要发送的数据
			DatagramPacket pack=new DatagramPacket(buf, 0, buf.length,InetAddress.getByName("127.0.0.1"),8090);
			datagramSocket.send(pack);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		datagramSocket.close();
	}
	//接收端
	@Test
	public void recive() {
		DatagramSocket ds=null;
		DatagramPacket dp=null;
		try {
			ds = new DatagramSocket(8090);
			byte[] b=new byte[1024];
			dp = new DatagramPacket(b, 0, b.length);
			ds.receive(dp);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		String str=new String(dp.getData(),0,dp.getLength());
		System.out.println(str);
		ds.close();	
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值