实验二 网络基础编程实验

一、实验目的:
  通过本实验,学习采用Socket(套接字)设计简单的网络数据收发程序,理解应用数据包是如何通过传输层进行传送的。 
二、实验内容:

        Socket(套接字)是一种抽象层,应用程序通过它来发送和接收数据,就像应用程序打开一个文件句柄,将数据读写到稳定的存储器上一样。一个socket允许应用程序添加到网络中,并与处于同一个网络中的其他应用程序进行通信。一台计算机上的应用程序向socket写入的信息能够被另一台计算机上的另一个应用程序读取,反之亦然。

        不同类型的socket与不同类型的底层协议族以及同一协议族中的不同协议栈相关联。现在TCP/IP协议族中的主要socket类型为流套接字(socketssockets)和数据报套接字(datagram sockets)。流套接字将TCP作为其端对端协议(底层使用IP协议),提供了一个可信赖的字节流服务。一个TCP/IP流套接字代表了TCP连接的一端。数据报套接字使用UDP协议(底层同样使用IP协议),提供了一个"尽力而为"(best-effort)的数据报服务,应用程序可以通过它发送最长65500字节的个人信息。一个TCP/IP套接字由一个互联网地址,一个端对端协议(TCP或UDP协议)以及一个端口号唯一确定。

2.1、采用TCP进行数据发送的简单程序(java)

TCPClient.jave

package edu.net;

import java.io.*; 
import java.net.*; 
class TCPClient { 

    public static void main(String argv[]) throws Exception 
    { 
        String sentence; 
        String modifiedSentence; 

        BufferedReader inFromUser = 
          new BufferedReader(new InputStreamReader(System.in)); 

        Socket clientSocket = new Socket("127.0.0.1", 6789); 

        DataOutputStream outToServer = 
          new DataOutputStream(clientSocket.getOutputStream()); 
        BufferedReader inFromServer = 
                new BufferedReader(new
                InputStreamReader(clientSocket.getInputStream())); 

              sentence = inFromUser.readLine(); 

              outToServer.writeBytes(sentence + '\n'); 

              modifiedSentence = inFromServer.readLine(); 

              System.out.println("FROM SERVER: " + modifiedSentence); 

              clientSocket.close(); 
                         
          } 
      } 

TCPServer.java

package edu.net;


import java.io.*; 
import java.net.*; 


class TCPServer { 


  private static ServerSocket welcomeSocket;


public static void main(String argv[]) throws Exception 
    { 
      String clientSentence; 
      String capitalizedSentence; 


      welcomeSocket = new ServerSocket(6789); 
  
      while(true) { 
  
            Socket connectionSocket = welcomeSocket.accept(); 


           BufferedReader inFromClient = 
              new BufferedReader(new
              InputStreamReader(connectionSocket.getInputStream())); 
           DataOutputStream  outToClient = 
                   new DataOutputStream(connectionSocket.getOutputStream()); 


                 clientSentence = inFromClient.readLine(); 


                 capitalizedSentence = clientSentence.toUpperCase() + '\n'; 


                 outToClient.writeBytes(capitalizedSentence); 
              } 
          } 
      } 

程序功能说明:

先运行服务端,在运行客户端,在客户端窗口输出英文字母,服务器转化为大写字母后返回显示在客户端窗口上。

程序运行结果:


2.2、采用UDP进行数据发送的简单程序(java)

UDPClient.java

package edu.net;

import java.io.*; 
import java.net.*; 
  
class UDPClient { 
    public static void main(String args[]) throws Exception 
    { 
  
      BufferedReader inFromUser = 
        new BufferedReader(new InputStreamReader(System.in)); 
  
      DatagramSocket clientSocket = new DatagramSocket(); 
  
      InetAddress IPAddress = InetAddress.getByName("127.0.0.1"); 
  
      byte[] sendData = new byte[1024]; 
      byte[] receiveData = new byte[1024]; 
  
      String sentence = inFromUser.readLine(); 
      sendData = sentence.getBytes();         
      DatagramPacket sendPacket = 
    	         new DatagramPacket(sendData, sendData.length, IPAddress, 9876); 
    	  
    	      clientSocket.send(sendPacket); 
    	  
    	      DatagramPacket receivePacket = 
    	         new DatagramPacket(receiveData, receiveData.length); 
    	  
    	      clientSocket.receive(receivePacket); 
    	  
    	      String modifiedSentence = 
    	          new String(receivePacket.getData()); 
    	  
    	      System.out.println("FROM SERVER:" + modifiedSentence); 
    	      clientSocket.close(); 
    	      } 
    	} 

UDPServer.java

package edu.net;

import java.net.*; 
  
class UDPServer { 
  private static DatagramSocket serverSocket;

public static void main(String args[]) throws Exception 
    { 
  
      serverSocket = new DatagramSocket(9876); 
  
      byte[] receiveData = new byte[1024]; 
      byte[] sendData  = new byte[1024]; 
  
      while(true) 
        { 
  
          DatagramPacket receivePacket = 
             new DatagramPacket(receiveData, receiveData.length); 
          serverSocket.receive(receivePacket); 

          String sentence = new String(receivePacket.getData()); 
  
          InetAddress IPAddress = receivePacket.getAddress(); 
  
          int port = receivePacket.getPort(); 
  
                      String capitalizedSentence = sentence.toUpperCase(); 

          sendData = capitalizedSentence.getBytes(); 
  
          DatagramPacket sendPacket = 
             new DatagramPacket(sendData, sendData.length, IPAddress, 
                               port); 
  
          serverSocket.send(sendPacket); 
        } 
    } 
} 

程序功能说明:

先运行服务端,在运行客户端,在客户端窗口输出英文字母,服务器转化为大写字母后返回显示在客户端窗口上。

程序运行结果:

2.3多线程\线程池对比

当一个客户端向一个已经被其他客户端占用的服务器发送连接请求时,虽然其在连接建立后即可向服务器端发送数据,服务器端在处理完已有客户端的请求前,却不会对新的客户端作出响应。

并行服务器:可以单独处理没一个连接,且不会产生干扰。并行服务器分为两种:一客户一线程和线程池。

每个新线程都会消耗系统资源:创建一个线程将占用CPU周期,而且每个线程都自己的数据结构(如,栈)也要消耗系统内存。另外,当一个线程阻塞(block)时,JVM将保存其状态,选择另外一个线程运行,并在上下文转换(contextswitch)时恢复阻塞线程的状态。随着线程数的增加,线程将消耗越来越多的系统资源。这将最终导致系统花费更多的时间来处理上下文转换和线程管理,更少的时间来对连接进行服务。那种情况下,加入一个额外的线程实际上可能增加客户端总服务时间。

我们可以通过限制总线程数并重复使用线程来避免这个问题。与为每个连接创建一个新的线程不同,服务器在启动时创建一个由固定数量线程组成的线程池(thread pool)。当一个新的客户端连接请求传入服务器,它将交给线程池中的一个线程处理。当该线程处理完这个客户端后,又返回线程池,并为下一次请求处理做好准备。如果连接请求到达服务器时,线程池中的所有线程都已经被占用,它们则在一个队列中等待,直到有空闲的线程可用。

TCPEchoClient.java

package com.tcpip.examp;
import java.io.IOException;  
import java.io.InputStream;  
import java.io.OutputStream;  
import java.net.Socket;  
import java.net.SocketException;  
import java.net.UnknownHostException;  
/** 
 * TCP客户端 
 *
 * 
 */  
public class TCPEchoClient  
{  
  
    private static Socket socket;

	public static void main(String[] args) throws UnknownHostException,  
            IOException  
    {  
        if (args.length < 2 || args.length > 3)  
        {  
            throw new IllegalArgumentException(  
                    "Parameter(s):<Server> <Word> [<Port>]");  
        }  
  
        // SerName or IP Address  
        String server = args[0];  
  
        // 0.1 获取传输文字的长度  
        byte[] data = args[1].getBytes();  
  
        // 0.2 获取端口号(严格的话要对这里进行一下端口的验证)  
        int serverPort = (args.length == 3) ? Integer.parseInt(args[2]) : 7;  
  
        socket = new Socket(server, serverPort);  
        System.out.println("Connected to server ..... Sending echo String");  
          
        // 2.输入/输出  
        InputStream in = socket.getInputStream();  
        OutputStream out = socket.getOutputStream();  
  
        // Sending encode string to server  
        out.write(data);  
  
        int totalBytesLength = 0;  
        int bytesRcvd;  
  
        while (totalBytesLength < data.length)  
        {  
            // 阻塞等待服务器端的返回  
            if ((bytesRcvd = in.read(data, totalBytesLength, data.length  
                    - totalBytesLength)) == -1)  
            {  
                throw new SocketException("Connection closed prematurely");  
            }  
              
            totalBytesLength += bytesRcvd;  
        }  
          
        System.out.println("Received:"+new String(data));  
          
        // 3.关闭  
        socket.close();  
    }  
}  

TCPEchoServer.java

package com.tcpip.examp;
  
  
import java.io.IOException;  
import java.io.InputStream;  
import java.io.OutputStream;  
import java.net.ServerSocket;  
import java.net.Socket;  
import java.net.SocketAddress;  
  
public class TCPEchoServer  
{  
    private static final int BUFFER_SIZE = 128;
	private static ServerSocket server;  
    public static void main(String[] args) throws IOException  
    {  
        if(args.length != 1)  
        {  
            throw new IllegalArgumentException("Parameter:<Port>");  
        }  
          
        // 获取服务器的端口  
        int serverPort = Integer.parseInt(args[0]);  
          
        server = new ServerSocket(serverPort);  
        System.out.println("Server has started!!!!");  
        int recvMsgSize = 0;  
        byte[] recvBuf = new byte[BUFFER_SIZE];  
          
        while(true)  
        {  
            System.out.println("Waiting from client connectting!!!");  
            // 阻塞等的客户端的连接  
            Socket socket = server.accept();  
              
            // 客户端的地址信息  
            SocketAddress address = socket.getRemoteSocketAddress();  
            System.out.println("Handling client at "+address+"\n");  
              
            InputStream in = socket.getInputStream();  
            OutputStream out = socket.getOutputStream();  
              
            while((recvMsgSize = in.read(recvBuf)) != -1)  
            {  
                out.write(recvBuf,0,recvMsgSize);  
            }  
              
            socket.close();  
        }  
    }  
  
}  

TCPEchoServerThread.java

package com.tcpip.examp;
import java.io.IOException;  
import java.net.ServerSocket;  
import java.net.Socket;  
import java.util.logging.Logger;  
  
/** 
 * 一客户一线程服务器处理 
 * 
 * 4.1 多任务处理
迭代服务器:当一个客户端向一个已经被其他客户端占用的服务器发送连接请求时,虽然其在连接建立后即可向服务器端发送数据,服务器端在处理完已有客户端的请求前,却不会对新的客户端作出响应。
并行服务器:可以单独处理没一个连接,且不会产生干扰。并行服务器分为两种:一客户一线程和线程池。
4.1.1 Java多线程
Java提供了两种在一个新线程中执行任务的方法:1)为Thread类定义一个带有run()方法的子类,在run()方法中包含要执行的任务,并实例化这个子类;或2)定义一个实现了Runnable接口的类,并在run()方法中包含要执行的任务,再将这个类的一个实例传递给Thread的构造函数。
 * 
 */  
public class TCPEchoServerThread  
{  
  
    private static ServerSocket serverSocket;

	public static void main(String[] args) throws IOException  
    {  
        if(args.length != 1)  
        {  
            throw new IllegalArgumentException("Parameter:<Port>");  
        }  
          
        // 日志记录器  
        Logger logger = Logger.getLogger("practical");  
          
        // 服务器侦听端口  
        int serverPort = Integer.parseInt(args[0]);  
        serverSocket = new ServerSocket(serverPort);  
          
        logger.info("Server is started!!!!");  
          
        while(true)  
        {  
            Socket socket = serverSocket.accept();  
              
            // 接收到客户端的请求后立即创建新的线程进行处理  
            Thread t = new Thread(new EchoProtocol(socket,logger));  
              
            t.start();  
              
            logger.info("Created and started Thread "+t.getName());  
        }  
    }  
  
}  

TCPEchoServerPool.java

package com.tcpip.examp;

import java.io.IOException;  
import java.net.ServerSocket;  
import java.net.Socket;  
import java.util.logging.Logger;  
  
/** 
 * 采用自定义线程池的方式实现多任务处理 
 每个新线程都会消耗系统资源:创建一个线程将占用CPU周期,而且每个线程都自己的数据结构(如,栈)也要消耗系统内存。另外,当一个线程阻塞(block)时,JVM将保存其状态,选择另外一个线程运行,并在上下文转换(context switch)时恢复阻塞线程的状态。随着线程数的增加,线程将消耗越来越多的系统资源。这将最终导致系统花费更多的时间来处理上下文转换和线程管理,更少的时间来对连接进行服务。那种情况下,加入一个额外的线程实际上可能增加客户端总服务时间。
我们可以通过限制总线程数并重复使用线程来避免这个问题。与为每个连接创建一个新的线程不同,服务器在启动时创建一个由固定数量线程组成的线程池(thread pool)。当一个新的客户端连接请求传入服务器,它将交给线程池中的一个线程处理。当该线程处理完这个客户端后,又返回线程池,并为下一次请求处理做好准备。如果连接请求到达服务器时,线程池中的所有线程都已经被占用,它们则在一个队列中等待,直到有空闲的线程可用。
 * 
 */  
public class TCPEchoServerPool  
{  
      
    public static void main(String[] args) throws IOException  
    {  
        if(args.length != 2)  
        {  
            throw new IllegalArgumentException("Parameter:<Port> <PoolSize>");  
        }  
          
        // 服务器侦听的端口号  
        int serverPort = Integer.parseInt(args[0]);  
          
        // 自定义线程池的大小  
        int poolSize = Integer.parseInt(args[1]);  
          
        // 日志记录器  
        final Logger logger = Logger.getLogger("practical");  
        final ServerSocket serverSocket = new ServerSocket(serverPort);  
          
        logger.info("Server is started!!!!");  
          
        /* 
         * 每个线程都反复循环,从(共享的)ServerSocket实例接收客户端连接。 
         * 当多个线程同时调用同一个ServerSocket实例的accept()方法时, 
         * 它们都将阻塞等待,直到一个新的连接成功建立。然后系统选择一个线程, 
         * 新建立的连接对应的Socket实例则只在选中的线程中返回。 
         * 其他线程则继续阻塞,直到成功建立下一个连接和选中另一个幸运的线程。 
         *  
         * */   
          
        for(int i = 0; i < poolSize; i++)  
        {  
            Thread t = new Thread()  
            {  
                @Override  
                public void run()  
                {  
                    while(true)  
                    {  
                        try  
                        {  
                            // 各个线程阻塞等待,知道有一个客户端连过来,当线程进行处理,其他的线程继续处理  
                            Socket socket = serverSocket.accept();  
                            EchoProtocol.handleEchoClient(socket, logger);  
                        }  
                        catch (IOException e)  
                        {  
                            // TODO Auto-generated catch block  
                            e.printStackTrace();  
                        }  
                    }  
                }  
                  
            };  
              
            t.start();  
              
            logger.info("Thread "+t.getName()+" has started!!!");  
        }  
    }  
  
}  

EchoProtocol.java

package com.tcpip.examp;
import java.io.IOException;  
import java.io.InputStream;  
import java.io.OutputStream;  
import java.net.Socket;  
import java.util.logging.Level;  
import java.util.logging.Logger;  
  
public class EchoProtocol implements Runnable {  
    private static final int BUFSIZE = 32; // Size (in bytes) of I/O buffer  
    private Socket clientSocket; // Socket connect to client  
    private Logger logger; // Server logger  
  
    public EchoProtocol(Socket clientSocket, Logger logger) {  
        this.clientSocket = clientSocket;  
        this.logger = logger;  
    }  
  
    public static void handleEchoClient(Socket clientSocket, Logger logger) {  
        try {  
            // Get the input and output I/O streams from socket  
            InputStream in = clientSocket.getInputStream();  
            OutputStream out = clientSocket.getOutputStream();  
  
            int recvMsgSize; // Size of received message  
            int totalBytesEchoed = 0; // Bytes received from client  
            byte[] echoBuffer = new byte[BUFSIZE]; // Receive Buffer  
            // Receive until client closes connection, indicated by -1  
            while ((recvMsgSize = in.read(echoBuffer)) != -1) {  
                out.write(echoBuffer, 0, recvMsgSize);  
                totalBytesEchoed += recvMsgSize;  
            }  
  
            logger.info("Client " + clientSocket.getRemoteSocketAddress() + ", echoed " + totalBytesEchoed + " bytes.");  
              
        } catch (IOException ex) {  
            logger.log(Level.WARNING, "Exception in echo protocol", ex);  
        } finally {  
            try {  
                clientSocket.close();  
            } catch (IOException e) {  
            }  
        }  
    }  
  
    public void run() {  
        handleEchoClient(this.clientSocket, this.logger);  
    }  
} 

——当服务器选择TCPEchoServer时,有结果:

首先根据相应格式设置参数:

服务端:

客户端:

——当服务器选择TCPEchoServeThreadr时,有结果:

——当服务器选择TCPEchoServerPool时,有结果:


2.4写一个简单的chat程序,编程语言不限。

 

【源代码如下】

服务端Server:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.List;

public class Server {
	private List<ServerThread> clients = null;
	
	public static void main(String[] args) {
		new Server().startUp();
	}
	
	private void startUp() {
		ServerSocket ss = null;
		Socket s = null;
		try {
			ss = new ServerSocket(5858);
			clients = new ArrayList<ServerThread>();
			while (true) {
				s = ss.accept();
				ServerThread st = new ServerThread(s);
				new Thread(st).start();
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (ss != null) 
					ss.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	private class ServerThread implements Runnable {
		private Socket s = null;
		private BufferedReader br;
		private PrintWriter out;
		private String name;
		private boolean flag = true;
		
		public ServerThread(Socket socket) throws IOException {
			this.s = socket;
			//BufferedReader : 提供通用的缓冲方式文本读取,readLine读取一个文本行, 从字符输入流中读取文本,
			//缓冲各个字符,从而提供字符、数组和行的高效读取。
			br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
			out = new PrintWriter(socket.getOutputStream(), true);
			String str = br.readLine();
			//name = str+"["+socket.getInetAddress().getHostAddress()+":"+socket.getPort()+"]";
			name = str;
			clients.add(this);
			send(name+"上线了");
		}
		
		private void send(String msg) {
			for (ServerThread st : clients)
				st.out.println(msg);
		}
		
		private void receive() throws IOException {
			String str = null;
			while ((str=br.readLine()) != null) {
				if (str.equalsIgnoreCase("quit")) {
					stop();
					out.println("disconnect");
					break;
				}
				send(name+":"+str);
			}
		}
		
		private void stop() {
			clients.remove(this);
			flag = false;
			send(name+"已经下线了");
		}

		@Override
		public void run() {
			try {
				while (true) {
					if (!flag) break;
					receive();
				}
			} catch (SocketException e) {
				stop();
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				try {
					if (s != null) 
						s.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		
	}
}

客户端1:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

public class Client {
	private Socket s;
	private BufferedReader br;
	//PrintWriter向文本输出流打印对象的格式化表示形式。
	private PrintWriter out;
	private boolean flag = true;
	
	public static void main(String[] args) {
		new Client().stratUp();
	}

	private void stratUp() {
		BufferedReader sbr = null;
		try {
			s = new Socket("127.0.0.1", 5858);
			out = new PrintWriter(s.getOutputStream(), true);
			br = new BufferedReader(new InputStreamReader(s.getInputStream()));
			out.println("端1");
//			out.println("端2");
			sbr = new BufferedReader(new InputStreamReader(System.in));
			//InputStreamReader 是字节流通向字符流的桥梁,它将字节流转换为字符流.
			//OutputStreamWriter是字符流通向字节流的桥梁,它将字符流转换为字节流.
			
			new Thread(new ClientThread()).start();
			String str = null;
			while (flag && (str=sbr.readLine())!=null) {
				if (!flag) break;
				out.println(str);
			}
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (s != null) s.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			try {
				if (sbr != null) s.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	private void receive() {
		try {
			String rs = br.readLine();
			if (rs.equalsIgnoreCase("disconnect")) {
				flag = false;
				System.out.println("点击回车退出");
			}
			System.out.println(rs);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	private class ClientThread implements Runnable {

		@Override
		public void run() {
			while (true) {
				if (!flag) break;
				receive();
			}
		}
		
	}

}

客户端2:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

public class Client2 {
	private Socket s;
	private BufferedReader br; 
	private PrintWriter out;
	private boolean flag = true;
	
	public static void main(String[] args) {
		new Client2().stratUp();
	}

	private void stratUp() {
		BufferedReader sbr = null;
		try {
			s = new Socket("127.0.0.2", 5858);
			out = new PrintWriter(s.getOutputStream(), true);
			br = new BufferedReader(new InputStreamReader(s.getInputStream()));
//			out.println("端1");
			out.println("端2");
			sbr = new BufferedReader(new InputStreamReader(System.in));
			
			new Thread(new ClientThread()).start();
			String str = null;
			while (flag && (str=sbr.readLine())!=null) {
				if (!flag) break;
				out.println(str);
			}
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (s != null) s.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			try {
				if (sbr != null) s.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	private void receive() {
		try {
			String rs = br.readLine();
			if (rs.equalsIgnoreCase("disconnect")) {
				flag = false;
				System.out.println("点击回车退出");
			}
			System.out.println(rs);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	private class ClientThread implements Runnable {

		@Override
		public void run() {
			while (true) {
				if (!flag) break;
				receive();
			}
		}
		
	}

}

【运行结果】

1、  运行服务端server

2、  运行客户端client

3、  运行客户端client2

4、在端1窗口内输入消息:你好,端2!在端2窗口内输入消息:你好,端1!屏幕中可显示两个端口相互通信,即实现两个客户端通过服务器相互交流的功能!


1. 了解媒体访问层(MAC): 输入: ipconfig/all 观察输出结果 可选参数: /release 释放当前通过DHCP获得的IP /renew 释放当前通过DHCP获得的IP并重新获得一个IP 提示:上述个命令只有是网卡的IP地址是设置为自动获取的才会有效果,设置为固定IP的将不会有什么变化。 观察输出结果,并回答以下问题: 利用IPCONFIG命令能查看到哪些地址信息? /displaydns 显示DNS缓存的记录. 2. NETSTAT Netstat是控制台命令,是一个监控TCP/IP网络的非常有用的工具,它可以显示路由表、实际的网络连接以及每一个网络接口设备的状态信息。Netstat用于显示与IP、TCP、UDP和ICMP协议相关的统计数据,一般用于检验本机各端口的网络连接情况。 输入下列命令和参数, 观察输出结果 netstat -a 显示建立在一个接口上的各种TCP和UDP会话 netstat -e 显示以太网统计数据,包括有问题的数据包 netstat -r 显示本地路由表的内容 netstat -s 显示每个协议的统计数据 3. ping 该命令是最常用的网络连通性测试的工具. 网际消息协议 (ICMP): 可以使用 ping 命令发送 ICMP 回应请求消息并记录收到 ICMP 回应回复消息。使用这些消息,可以检测网络或主机通讯故障并解决常见的 TCP/IP 连接问题。 ICMP 消息描述 回应请求: 确定 IP 节点(主机或路由器)能否在网络上使用。 回应回复: 回复 ICMP 回应请求。 无法访问目标: 通知主机数据报无法传递。 源减慢 :通知主机由于拥挤而降低发送数据报的速率。 重定向: 通知首选路由的主机。 超时: 指明 IP 数据报的生存时间 (TTL) 已到期。 参数: -t Ping 指定的计算机直到中断。 -l length 发送包含由 length 指定的数据量的 ECHO 数据包。默认为 32 字节;最大值是 65,527。 ping www.jyu.edu.cn ping www.sina.com.cn 观察输出结果,并回答以下问题 (2)PING www.jyu.edu.cn显示PING不通,可能是什么原因造成的? (3)PING一个IP时,返回的结果中包含一个时间和TTL数值,这个参数分别代表什么含义?由这个时间值能大致判断什么情况? (4)PING一个IP时,返回的结果中的TTL数值有些在240-255之间,有些在110-130之间,有些在50-65之间,这些不同的值相差很大,是什么原因?根据这些不同的数值能大致判断什么? 4. tracert 该工具类似UNIX中的traceroute,它报告你的计算机和目的地之间的每个接口的IP地址和名称。如果PING 失败,用tracert可以知道问题出在那里. 如果有连通性问题,可以使用 tracert 命令来检查到达的目标 IP 地址的路径并记录结果。tracert 命令显示用于将数据包从计算机传递到目标位置的一组 IP 路由器,以及每个跃点所需的时间。如果数据包不能传递到目标,tracert 命令将显示成功转发数据包的最后一个路由器。 比较 tracert www.jyu.edu.cn tracert www.sina.edu.cn 观察输出结果,并回答以下问题: (1)tracert某一个网站显示的跳数跟PING同一个网站返回的TTL值有什么关联?如果你已经知道了PING一个网站的TTL值是45,能不能直接计算出tracert该网站的跳数?怎么计算的? 5. pathping pathping 命令是路由跟踪工具,它将 ping 和 tracert 命令的功能与非这些工具提供的其他信息组合在一起。经过一段时间,pathping 命令将数据包发送到最终目标位置途中经过的每个路由器。pathping 命令与工具tracert类似,请比较tracert的结果。 6. nslookup Nslookup显示可用来诊断域名系统 (DNS) 基础结构的信息。只有在已安装 TCP/IP 协议的情况下才可以使用 Nslookup 命令行工具。 观察输出结果,并回答以下问题: (1)输出结果中的域名解析的IP是怎么来的?如何判断
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值