计算机网络是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统。
这两大协议都是位于OSI模型的传输层
TCP:传输控制协议
TCP提供了一种面向连接的、可靠的字节流连接
UDP:用户数据报协议
UDP是不可靠的,他不能保证数据包能安全无误的到达最终目的
UDP是一个简单的面向数据包的运输层协议:进程的每个输出操作都正好产生一个UDP数据包
服务端 1、套接字 //常用构成方法 ServerSocket()//创建一个非绑定服务器的套接字 ServerSocket(int port)//创建绑定服务器的套接字 2、服务器对端口中客户端的监听方法 accept();//监听,并返回一个Socket对象,没有客户端连接的时候会发生阻塞 客户端 1、套接字 Socket(InetAddress address,int port)//指定客户端要发送信息的目的主机和指定的端口
1、图解(思路所在,很重要)
2、代码实现
服务端
import java.io.*; import java.net.ServerSocket; import java.net.Socket; import java.util.Scanner; public class Service { private static ServerSocket serverSocket=null; private static InputStreamReader bis=null; private static OutputStreamWriter bos=null; private static Socket socket=null; public static void main(String[] args) { try { serverSocket=new ServerSocket(8888);//监听端口 socket=serverSocket.accept();//等待客户机的连接 acceptData(socket);//接收数据的方法 while(true){ sendData(socket);//发送数据的方法 } } catch (IOException e) { e.printStackTrace(); } } //接收数据的方法实现 public static void acceptData(Socket socket){ if(socket == null && socket.isClosed()){ System.out.println("连接为空"); return; } new Thread(){//通过线程来实现同步监听 @Override public void run() { while(true) { try { //进行数据流的操作 bis = new InputStreamReader(socket.getInputStream()); char[] content=new char[1024]; while(bis.read(content)!=-1){ System.out.println(new String(content)); } } catch (IOException e) { e.printStackTrace(); } } } }.start(); } //发送数据的方法实现 public static void sendData(Socket socket) throws IOException { if(socket==null&&socket.isClosed()){ System.out.println("连接为空"); return; } //流的操作 bos=new OutputStreamWriter(socket.getOutputStream()); String content=new Scanner(System.in).next(); bos.write(content); bos.flush(); } }
客户端
import java.io.*; import java.net.InetAddress; import java.net.Socket; import java.util.Scanner; public class Client { private static Socket clientSocket=null; private static InputStreamReader bis=null; private static OutputStreamWriter bos=null; public static void main(String[] args) { try { //指定客户端访问的服务端的IP地址和端口号 clientSocket=new Socket(InetAddress.getLocalHost(),8888); while(true) { sendData(clientSocket);//发送数据方法 acceptData(clientSocket);//接收数据方法 } } catch (IOException e) { e.printStackTrace(); } } //接收数据的方法实现 public static void acceptData(Socket socket){ if(socket==null&& socket.isClosed()){ System.out.println("连接为空"); return; } //流操作 try { bis=new InputStreamReader(socket.getInputStream()); char[] content=new char[1024]; while(bis.read(content)!=-1) { System.out.println(new String(content)); } } catch (IOException e) { e.printStackTrace(); } } //发送数据的方法实现 public static void sendData(Socket socket){ if(socket==null&&socket.isClosed()){ System.out.println("连接为空"); return; } //流操作 try { bos=new OutputStreamWriter(socket.getOutputStream()); String content=new Scanner(System.in).next(); bos.write(content); bos.flush(); } catch (IOException e) { e.printStackTrace(); } } }
3、总结
TCP模式的网络编程是可靠的数据传输,服务器监听着一个端口,等待客户端来连接,形成Socket对象,利用这个Socket对象来进行服务端和客户端的数据传输,而数据传输靠的就是底层流的操作。
DaragramSocket()//创建一个数据包套接字,有内部自动分配一个监听端口 DaragramSocket(byte[] buf,int offset,int length,IneetAddress address,int port) //创建一个指定内容和大小以及目标主机的IP地址和端口号的数据包套接字 DatagramSocket(int port)//绑定监听的端口 DatagramPacket(byte[] buf,int length)//创建字节数组来接收数据包 1、发送数据 利用套接字的send(DaragramPacket packet)方法发送数据包 2、接收数据 利用套接字的receive(DaragramPacket packet)方法来接收数据包
1、图解(思路所在,很重要)
2、代码实现
服务端
import java.io.IOException; import java.net.*; import java.util.Scanner; public class Service { private static DatagramSocket datagramSocket=null; private static String content=""; public static void main(String[] args) { try { datagramSocket=new DatagramSocket(114);//绑定端口 } catch (SocketException e) { e.printStackTrace(); } Service s=new Service(); s.acceptData();//接收数据包的方法 s.initSocket();//发送数据包的方法(代理方法) } public void initSocket(){ try { while(true) { content = new Scanner(System.in).next(); sendData(content);//真正发送数据包的方法 } } catch(Exception e){ e.printStackTrace(); } } /** * 通过输入的内容创建一个数据包,并且发送该数据包 * @param content * @throws IOException */ private void sendData(String content) throws IOException { if(content!=null) { byte[] con = content.getBytes(); //创建一个内容为con数组的数据包 DatagramPacket sendPacket = new DatagramPacket(con, con.length, InetAddress.getLocalHost(), 115); datagramSocket.send(sendPacket);//通过端口将数据发送出去 } } /** * 通过开创一个线程来不断监听端口 */ private void acceptData(){ new Thread(){ @Override public void run() {//通过线程来监听端口 while(true){ byte[] content=new byte[1024]; DatagramPacket acceptPacket=null; try { //创建一个空的数据包 acceptPacket=new DatagramPacket(content,content.length); datagramSocket.receive(acceptPacket);//将接收到的数据包存放到空的数据包中 } catch (IOException e) { e.printStackTrace(); } System.out.println(new String(acceptPacket.getData(),0,content.length)); } } }.start(); } }
客户端(写法与服务端一样,但需要改变监听的端口和发送数据的端口)
import java.io.IOException; import java.net.*; import java.util.Scanner; public class Client { private static DatagramSocket datagramSocket=null; public static void main(String[] args) { try { datagramSocket=new DatagramSocket(115); acceptData(); while(true) { String con = new Scanner(System.in).next(); sendData(con); } } catch (IOException e) { e.printStackTrace(); } } public static void sendData(String content) throws IOException { byte[] con=content.getBytes(); DatagramPacket sendPacket=new DatagramPacket(con,0,con.length, InetAddress.getLocalHost(),114); datagramSocket.send(sendPacket); } public static void acceptData(){ new Thread(){ @Override public void run() { while(true) { byte[] con=new byte[1024]; DatagramPacket acceptPacket=null; try { acceptPacket=new DatagramPacket(con,con.length); datagramSocket.receive(acceptPacket); } catch (IOException e) { e.printStackTrace(); } System.out.println(new String(acceptPacket.getData(),0,con.length)); } } }.start(); } }
3、总结
UDP编程是一种无连接的编程,而且传输的是数据包,由于要指定数据包的大小,所以在传输途中丢失数据是很有可能发生的,但是其传输速度会比TCP传输的速度快,所以这两种模式的数据传输的优缺点也就出来了
notes:
图和代码都是本人靠理解所画所写,其中不免有不足之处,还望理解并指出,十分感谢。