函数调用(函数指针)

时间限制: 1 Sec 内存限制: 128 MB

题目描述

定义并实现三个函数:
第一个函数是整数函数,返回类型为整数,参数是一个整数变量,操作是求该变量的平方值
第二个函数是浮点数函数,返回类型为浮点数,参数是一个浮点数变量,操作是求该变量的平方根值。求平方根可以使用函数sqrt(浮点参数),将返回该参数的平方根,在VC中需要头文件cmath。
第三个函数是字符串函数,无返回值,参数是一个字符串指针,操作是把这个字符串内所有小写字母变成大写。
要求:定义三个函数指针分别指向这三个函数,然后根据调用类型使用函数指针来调用这三个函数。不能直接调用这三个函数。
如果类型为I,则通过指针调用整数函数;如果类型为F,则通过指针调用浮点数函数;如果类型为S,则通过指针调用字符串函数

输入

第一行输入一个t表示有t个测试实例
每行先输入一个大写字母,表示调用类型,然后再输入相应的参数
依次输入t行

输出

每行输出调用函数后的结果

样例输入

5
S shenzhen
I 25
F 6.25
I 31
S China

样例输出

SHENZHEN
625
2.5
961
CHINA

提示

解决方案

#include <iostream>
#include <cmath>

int square(int number) {
    return number * number;
}

double square_root(double number) {
    return sqrt(number);
}

void to_upper_case(char *string) {
    while (char ch = *string) {
        if ('a' <= ch && ch <= 'z') {
            *string -= ('a' - 'A');
        }
        string += 1;
    }
}

int main() {
    size_t T;
    std::cin >> T;
    while (T--) {
        char type;
        std::cin >> type;
        switch (type) {
            case 'I': {
                int number;
                std::cin >> number;
                int (*function_ptr)(int) = square;
                std::cout << function_ptr(number) << std::endl;
                break;
            }
            case 'F': {
                double number;
                std::cin >> number;
                double (*function_ptr)(double) = square_root;
                std::cout << function_ptr(number) << std::endl;
                break;
            }
            case 'S': {
                char string[1024];
                std::cin >> string;
                void (*function_ptr)(char *) = to_upper_case;
                function_ptr(string);
                std::cout << string << std::endl;
                break;
            }
            default:
                exit(-1);
        }
    }
    return 0;
}

字符串比较(指针与字符)

时间限制: 1 Sec 内存限制: 128 MB

题目描述

编写一个函数比较两个字符串,参数是两个字符指针(要求显式定义,例如char *S, char *T),比较字符串S和T的大小。如果S大于T,则返回1,如果S小于T则返回-1,如果S与T相等则返回0。
比较规则:
1.把两个字符串的相同位置上的字符进行比较,字符的大小比较以ASCII值为准
2.在比较中,如果字符串S的字符大于字符串T的字符的数量超过小于的数量,则认为S大于T,如果等于则S等于T,如果小于则S小于T
例如S为aaccdd,T为eebbbb,每个位置比较得到S前两个字母都小于T,但后4个字母都大于T,最终认为S大于T
3.如果两个字符串长度不同,则更长的字符串为大
在主函数中输入两个字符串,并调用该函数进行判断,在判断函数中必须使用函数参数的指针进行字符比较

输入

输入t表示有t个测试实例
接着每两行输入两个字符串
依次输入t个实例

输出

每行输出一个实例的比较结果

样例输入

3
aaccdd
eebbbb
AAbb++
aaEE*-
zznnkk
aaaaaaa

样例输出

1
0
-1

提示

解决方案

#include <iostream>
#include <cstring>

int strcmp(char *str1, char *str2) {
    size_t str1_length = strlen(str1), str2_length = strlen(str2);
    if (str1_length > str2_length) {
        return 1;
    } else if (str1_length < str2_length) {
        return -1;
    }
    unsigned int value1 = 0, value2 = 0;
    while (*str1 != '\0') {
        if (*str1 == *str2) {
            continue;
        }
        if (*(str1++) > *(str2++)) {
            value1 += 1;
        } else {
            value2 += 1;
        }
    }
    if (value1 > value2) {
        return 1;
    } else if (value1 < value2) {
        return -1;
    } else {
        return 0;
    }
}

int main() {
    size_t T;
    std::cin >> T;
    while (T--) {
        char str1[1024], str2[1024];
        std::cin >> str1 >> str2;
        std::cout << strcmp(str1, str2) << std::endl;
    }
    return 0;
}

月份查询(指针数组)

时间限制: 1 Sec 内存限制: 128 MB

题目描述

已知每个月份的英文单词如下,要求创建一个指针数组,数组中的每个指针指向一个月份的英文字符串,要求根据输入的月份数字输出相应的英文单词
1月 January
2月 February
3月 March
4月 April
5月 May
6月 June
7月 July
8月 August
9月 September
10月 October
11月 November
12月 December

输入

第一行输入t表示t个测试实例
接着每行输入一个月份的数字
依次输入t行

输出

每行输出相应的月份的字符串,若没有这个月份的单词,输出error

样例输入

3
5
11
15

样例输出

May
November
error

提示

解决方案

#include <iostream>

int main() {
    const char *calendar[] = {"January", "February", "March",
                              "April", "May", "June",
                              "July", "August", "September",
                              "October", "November", "December"};
    size_t T;
    std::cin >> T;
    while (T--) {
        unsigned int month;
        std::cin >> month;
        if (1 <= month && month <= 12) {
            std::cout << calendar[month - 1] << std::endl;
        } else {
            std::cout << "error" << std::endl;
        }
    }
    return 0;
}

货币兑换(指针与常量)

时间限制: 1 Sec 内存限制: 128 MB

题目描述

设定以下汇率常量
美元汇率为6.2619,表示1美元兑换6.2619元人民币
欧元汇率为6.6744,表示1欧元兑换6.6744元人民币
日元汇率为0.0516,表示1元日元兑换0.0516元人民币
港币汇率为0.8065,表示1元港币币兑换0.8065元人民币
定义一个常量指针,根据需求指针指向不同的汇率,然后计算出各种货币兑换为人民币的数量
要求:不能直接使用汇率常量进行计算,必须使用常量指针,只能使用一个指针

输入

输入一个t表示有t个测试实例
每行先输入一个字母,表示货币类型,然后再输入一个数字(正浮点数),表示货币数量
D表示美元,E表示欧元,Y表示日圆,H表示港币
依次输入t行

输出

每行输出兑换后的人民币数量,保留4位小数
在C++中,输出指定精度的参考代码如下:

#include <iostream>
#include <iomanip> //必须包含这个头文件

using namespace std;

void main( )
{
  double a =3.141596;
  cout<<fixed<<setprecision(3)<<a<<endl;  //输出小数点后3位
}

样例输入

4
Y 10000
D 88.3
H 200
E 73.1

样例输出

516.0000
552.9258
161.3000
487.8986

提示

解决方案

#include <iostream>
#include <iomanip>

const double USD_CNY = 6.2619, EUR_CNY = 6.6744, JPY_CNY = 0.0516, HKD_CNY = 0.8065;

int main() {
    size_t T;
    std::cin >> T;
    const double *exchange_rate = nullptr;
    while (T--) {
        char type;
        double money;
        std::cin >> type >> money;
        switch (type) {
            case 'D':
                exchange_rate = &USD_CNY;
                break;
            case 'E':
                exchange_rate = &EUR_CNY;
                break;
            case 'Y':
                exchange_rate = &JPY_CNY;
                break;
            case 'H':
                exchange_rate = &HKD_CNY;
                break;
            default:
                exit(-1);
        }
        std::cout << std::fixed << std::setprecision(4) << (money * *exchange_rate) << std::endl;
    }
    return 0;
}

密钥加密法(指针应用)

时间限制: 1 Sec 内存限制: 128 MB

题目描述

有一种方式是使用密钥进行加密的方法,就是对明文的每个字符使用密钥上对应的密码进行加密,最终得到密文
例如明文是abcde,密钥是234,那么加密方法就是a对应密钥的2,也就是a偏移2位转化为c;明文b对应密钥的3,就是b偏移3位转化为e,同理c偏移4位转化为g。这时候密钥已经使用完,那么又重头开始使用。因此明文的d对应密钥的2,转化为f,明文的e对应密钥的3转化为h。所以明文abcde,密钥234,经过加密后得到密文是cegfh。
如果字母偏移的位数超过26个字母范围,则循环偏移,例如字母z偏移2位,就是转化为b,同理字母x偏移5位就是转化为c
要求:使用三个指针p、q、s分别指向明文、密钥和密文,然后使用指针p和q来访问每个位置的字符,进行加密得到密文存储在指针s指向的位置。
除了变量定义和输入数据,其他过程都不能使用数组下标法,必须使用三个指针来访问明文、密钥和密文。
提示:当指针q已经移动到密钥的末尾,但明文仍然没有结束,那么q就跳回密钥头

输入

第一行输入t表示有t个测试实例
第二行输入一个字符串,表示第一个实例的明文
第三行输入一个数字串,表示第一个实例的密钥
依次输入t个实例

输出

每行输出加密后的密文

样例输入

2
abcde
234
XenOS
56

样例输出

cegfh
CksUX

提示

解决方案

#include <iostream>
#include <cstring>

typedef char *string;

char addCharRegular(char ch, int index) {
    index = index - '0';
    if ('a' <= ch && ch <= 'z') {
        return ((ch - 'a') + index) % 26 + 'a';
    } else {
        return ((ch - 'A') + index) % 26 + 'A';
    }
}

int main() {
    size_t T;
    std::cin >> T;
    while (T--) {
        const auto plaintext = new char[1024], cipher = new char[1024], ciphertext = new char[1024] {};
        std::cin >> plaintext >> cipher;
        size_t plaintext_length = strlen(plaintext), cipher_length = strlen(cipher);
        auto plaintext_ptr = plaintext, cipher_ptr = cipher, ciphertext_ptr = ciphertext;
        const auto plaintext_end = plaintext + plaintext_length, cipher_end = cipher + cipher_length;
        while (plaintext_ptr != plaintext_end) {
            *(ciphertext_ptr++) = addCharRegular(*(plaintext_ptr++), *(cipher_ptr++));
            if (cipher_ptr == cipher_end) {
                cipher_ptr = cipher;
            }
        }
        *ciphertext_ptr = '\0';
        std::cout << ciphertext << std::endl;
    }
    return 0;
}

动态数组(指针与数组)

时间限制: 1 Sec  内存限制: 128 MB

题目描述

一开始未知数组长度,根据要求创建不同类型的指针,并且使用指针创建相应长度的数组,然后再完成不同的要求
若要求创建整数数组,计算数组内所有数据的平均值
若要求创建字符数组,找出数组内的最大字母
若要求创建浮点数数组,找出数组的最小值
要求程序整个过程不能使用数组下标,从数组创建、输入到搜索、比较、计算,到输出都必须使用指针
提示:使用new关键字

输入

第一行输入t表示有t个测试实例
第二行先输入一个大写字母表示数组类型,I表示整数类型,C表示字符类型,F表示浮点数类型;然后输入n表示数组长度。
第三行输入n个数据
依次输入t个实例

输出

每个根据不同的数组类型输出相应的结果

样例输入

3
C 5
A D E B C
I 6
22 55 77 33 88 55
F 4
3.1 1.9 6.5 4.8

样例输出

E
55
1.9

提示

解决方案

不明白这种要求存在的意义。它对于让学生更好地理解指针这个问题上没有任何意义,反而降低代码质量。对于这个问题,我建议你去阅读《征服C指针》之类的图书,或许对你帮助会很大。

顺便一提,*(p+5)p[5]的语法糖,也就是说,p[5]是前者的简化形式,方便输入等。因此,在这个时候甚至5[p]p[5]也是一样的,不过别写成这样。具体内容详见上述图书。

#include <iostream>

int getAverageValue(const int *array, size_t size) {
    int sum = 0;
    size_t times = size;
    while (times--) {
        sum += *(array++);
    }
    return (sum / static_cast<int>(size));
}

char getMaximumChar(const char *array, size_t size) {
    char maxChar = *array;
    while (size--) {
        if (maxChar < *array) {
            maxChar = *array;
        }
        array += 1;
    }
    return maxChar;
}

double getMinimumFloat(const double *array, size_t size) {
    double minDouble = *array;
    while (size--) {
        if (minDouble > *array) {
            minDouble = *array;
        }
        array += 1;
    }
    return minDouble;
}

template<typename T>
T *handleArray(size_t size) {
    T *array = new T[size];
    for (size_t i = 0; i < size; ++i) {
        std::cin >> *(array + i);
    }
    return array;
}

int main() {
    size_t T;
    std::cin >> T;
    while (T--) {
        char type;
        size_t size;
        std::cin >> type >> size;
        switch (type) {
            case 'I': {
                const int *array = handleArray<int>(size);
                std::cout << getAverageValue(array, size) << std::endl;
                break;
            }
            case 'C': {
                const char *array = handleArray<char>(size);
                std::cout << getMaximumChar(array, size) << std::endl;
                break;
            }
            case 'F': {
                const double *array = handleArray<double>(size);
                std::cout << getMinimumFloat(array, size) << std::endl;
                break;
            }
            default:
                exit(-1);
        }
    }
    return 0;
}

成绩查询(指针运算)

时间限制: 1 Sec 内存限制: 128 MB

题目描述

已知一组学生成绩,然后根据输入的序号查询成绩
要求:

  1. 使用一个整数数组存储学生成绩,假设元素数是n。
  2. 使用一个指针指向数组中间元素,即n/2的位置。
  3. 使用++和–运算符,求出数组中间元素的前一个成绩和后一个成绩
  4. 输入一个序号,然后计算这个序号的元素和中间元素的距离,然后使用指针去访问
    例如有11个学生,指针指向中间的学生也就是第6个学生,若输入序号3,即查询第3个学生的成绩,第3和第6之间距离为3,那么指针应该怎么运算呢???
    如果有两个中间学生,则将后面那个看为中间学生。
  5. 整个程序除了输入时可以使用数组下标,其他部分尽量使用使用指针进行访问。

输入

第一行输入t表示有t个测试实例
第二行先输入n,表示有n个学生,然后再输入n个成绩(正整数)
第三行输入1个序号,表示要查询成绩的学生的序号。
依次输入t个实例
按自然意义,序号是从1开始计算
提示:在数组中是从……..

输出

对于每个测试实例:
第一行输出数组中间元素的前一个成绩和后一个成绩
第二行根据序号输出1个成绩

样例输入

2
7 66 99 88 44 77 33 11
2
11 60 80 50 20 90 35 70 40 10 95 30
9

样例输出

88 77
99
90 70
10

提示

解决方案

不想评论了…

#include <iostream>
#include <algorithm>

inline const unsigned int *getArrayMiddlePointer(const unsigned int *array, const size_t size) {
    return array + (size / 2);
}

int main() {
    size_t T;
    std::cin >> T;
    while (T--) {
        size_t ARRAY_SIZE;
        std::cin >> ARRAY_SIZE;
        auto *array = new unsigned int[ARRAY_SIZE];
        for (size_t i = 0; i < ARRAY_SIZE; ++i) {
            std::cin >> array[i];
        }
        auto ptr = getArrayMiddlePointer(array, ARRAY_SIZE);
        std::cout << *(--ptr) << ' ';
        ptr = getArrayMiddlePointer(array, ARRAY_SIZE);
        std::cout << *(++ptr) << std::endl;
        size_t number;
        std::cin >> number;
        const auto delta = (ARRAY_SIZE / 2) + 1 - number;
        ptr = getArrayMiddlePointer(array, ARRAY_SIZE);
        std::cout << *(ptr - delta) << std::endl;
    }
    return 0;
}

数字判断(指针为函数参数)

时间限制: 1 Sec 内存限制: 128 MB

题目描述

输入一个字符串,判断这个字符串是否一个完全整数值的字符串,例如输入”1234″,那么表示整数1234,输入”12a3″就表示只是一个字符串,不是一个整数
要求编写函数isNumber,参数是一个字符指针,返回值是整数类型
如果字符串表示一个整数,则计算出这个整数并且返回
如果字符串不是表示一个整数,则返回-1
主函数必须调用isNumber来判断字符串,不能使用任何C++自带或第三方的类似函数

输入

输入t表示有t个测试实例
每行输入一个字符串
依次输入t行

输出

每行输出判断结果

样例输入

3
1234
567a
0890

样例输出

1234
-1
890

提示

解决方案

有一说一,这题搞得我很火大。本来几句话就秒掉的题目,没想到后台数据竟然一份换行符是LR,一份是CRLF…搞得加了一堆删白符的代码,看着就不爽…早知道不这么写了。而且要是想让学生写的代码更好,至少也应该先讲过相关内容吧?不然一起怪OJ有问题很好玩么?

总而言之,说归说,最后还是一句话:我菜。

#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>

bool isDigit(const char ch) {
    return ('0' <= ch) && (ch <= '9');
}

bool isNumber(const char *string, size_t size) {
    return std::find_if(string, (string + size), [](char ch) { return !isDigit(ch); }) == (string + size);
}

int main() {
    size_t T;
    std::cin >> T;
    if (std::cin.get() == '\r') {
        std::cin.get();
    }
    char string[1024]{};
    while (T--) {
        std::cin.getline(string, 1024);
//        std::cout << string << std::endl;
        size_t string_length = strlen(string);
        if (string[string_length - 1] == '\r' || string[string_length - 1] == '\n') {
            string[string_length - 1] = '\0';
            string_length -= 1;
        }
        size_t leading_zero_amount = std::find_if_not(string, string + string_length, [](char ch) { return ch == '0'; }) - string;
        std::cout << (isNumber(string, string_length) ? std::string(string + leading_zero_amount, string + string_length) : "-1") << std::endl;
    }
    return 0;
}

三数论大小(指针)

时间限制: 1 Sec 内存限制: 128 MB

题目描述

输入三个整数,然后按照从大到小的顺序输出数值。
要求:用三个指针分别指向这三个整数,排序过程必须通过这三个指针来操作,不能直接访问这三个整数
输出时,必须使用这三个指针,不能使用存储三个整数的变量

输入

第一行输入t表示有t个测试实例
第二行起,每行输入三个整数
输入t行

输出

每行按照从大到小的顺序输出每个实例
在每行中,每个数据输出后都带有一个空格,即使该行最后一个数据输出后也要再输出一个空格

样例输入

3
2 4 6
88 99 77
111 333 222

样例输出

6 4 2 
99 88 77 
333 222 111 

提示

解决方案

#include <iostream>
#include <algorithm>

const size_t ARRAY_SIZE = 3;

int main() {
    unsigned int T;
    std::cin >> T;
    while (T--) {
        int integer_array[ARRAY_SIZE]{}, *integer_ptr_array[ARRAY_SIZE]{};
        for (size_t i = 0; i < ARRAY_SIZE; ++i) {
            std::cin >> integer_array[i];
            integer_ptr_array[i] = integer_array + i;
        }
        for (size_t i1 = 0; i1 < (ARRAY_SIZE - 1); ++i1) {
            for (size_t i2 = 0; i2 < (ARRAY_SIZE - i1 - 1); ++i2) {
                if (*integer_ptr_array[i2] < *integer_ptr_array[i2 + 1]) {
                    // swap pointers
                    auto tmp_ptr = integer_ptr_array[i2];
                    integer_ptr_array[i2] = integer_ptr_array[i2 + 1];
                    integer_ptr_array[i2 + 1] = tmp_ptr;
                }
            }
        }
        for (auto item : integer_ptr_array) {
            std::cout << *item << ' ';
        }
        std::cout << std::endl;
    }
    return 0;
}

VLAN Lab

让队友和我一起折腾到了六点多,有点愧疚,感谢各位大佬支持。

记录一下踩雷的历史,希望对各位有所帮助,如果文中存在差错,还望各位指点。写这些的目的并不是为了让某些懒人直接照搬进去实验报告的,我还是希望能够营造一个大家积极交流而进步的氛围,而不是放任有些人能混过去就行的心态,让开源给抄袭提供便利。如果是这样的话我宁愿自己删掉这些文章。

这次的环境是:

  • 机房的电脑4台,全部是Windows 7系统。其中一台电脑使用Xshell,通过串口连接并配置交换机。
  • Quidway S5700系列交换机1台,Quidway S3700系列交换机1台。

…并不是我故意找了两台不一样的,而是我所在的位置上的机柜里就是这样的。这样的情况带来的问题就是有些命令不大一样,需要先翻手册才知道。当然你要是因为这个就黑说老师的PPT不对就有点过了,PPT上面的内容个人认为最多算是启发性质的、大方向上的教程,并且针对的交换机型号、硬件版本、固件版本不能总是和你所在的环境一样,更多的细节上的问题你总是需要自己想办法去解决和适应。

画个重点:2019年底的时候,计软3楼某些实验室已经更换了全套全新的交换机和路由器,颇有财大气粗、大材小用的气势。至于为什么这么说,等你去到实验室感受一下就知道了。我觉得这个时候你大概不会再需要头疼我遇到的很多问题了。

CONSOLE登录

为了配置交换机,这里你需要用串口来控制你的交换机。以前如果你有折腾过普通家用的路由器/网管交换机,你通常都是访问路由器的Web管理界面(例如浏览器访问http://192.168.1.1/)来进行配置,现在就不一样了。原因比较多,就不在这里废话了。

正常情况下,你应该可以看到交换机上面的CONSOLE口有一根线连到了某台电脑的RS-232(这个是我瞎说的)口上,这个时候就用这台电脑来配置交换机吧。

PPT里的示例使用的是超级终端,不过我使用的是Xshell,像这样子新建一个连接,然后选择串口SERIAL

VLAN_LAB_1.jpg
Xshell 新建会话

先别急着确定,我一般会习惯性地先看看端口号:

VLAN_LAB_2.jpg
右击此电脑->管理->设备管理器

COM1没错了,记住它,到左侧的SERIAL中确认一下各项参数是否正确,然后就可以连接了。

VLAN_LAB_3.jpg
Xshell 连接成功

连接上之后,可以直接输入一个问号?来查看帮助。平时输入命令的时候,可以用TAB来提示相关词,这个就是键盘上那个制表符,我强烈建议你在控制台里多利用提示和补全,而不是YY。

然后根据实验报告的要求,你可以到各种视图中转悠转悠熟悉一下操作:

VLAN_LAB_4.jpg
进入system-view

什么?你说PPT上的端口不对?你看过文档或是display看过了吗?

VLAN_LAB_5.png
端口要具体情况具体分析

这里就不再多说什么了,端口各种配置各位就自行看文档发掘吧。

VLAN基本配置

实验要求大概是这样的:

VLAN_LAB_6.png
实验要求 图源PPT

按图连接好实验设备,PC1、PC2、交换机的IP地址分别为10.110.10.1、10.110.10.2、10.110.10.3,子网掩码均设置为255.255.255.0。建立VLAN2、VLAN3,通过配置将端口Ethernet 0/3包含到VLAN2中,将端口Ethernet 0/4包含到VLAN3中,并使用PING命令检查VLAN工作情况,测试PC1、PC2、交换机之间能否PING成功。
将端口Ethernet 0/4包含到VLAN2中,并使用PING命令检查VLAN工作情况,测试PC1、PC2 、交换机之间能否PING成功。

实验要求 源PPT

简单来讲就是要把两台PC设置在不同VLAN中,然后测试一下它们在没有其它因素的时候能不能通信。(废话嘛…这要是可以还要VLAN干吗哦…)

所以我们先把PC1、PC2分别连接到交换机的Ethernet 0/0/3、Ethernet 0/0/4上。正常情况下,连接正确的时候你能看到交换机上对应数字的灯在闪烁。连接完成后我们在PC上设置一下IP地址和子网掩码,就像这样:

VLAN_LAB_7.png
手动设置IP地址

你应该能找到它在哪里吧…控制面板->网络和和共享中心->本地连接->属性->IPv4。我感觉可能还是很多同学不知道这个选项在哪,也不知道为啥平时自己通常都不需要这么设置就能上网,这个主要是因为平时你所处的网络内都有DHCP服务器负责为你下发IP地址,只要PC是默认的自动获取IP地址,你通常都不需要干预就能正常上网,感兴趣的话我建议自己去查一下。

至于交换机的IP地址的设置…如果你以前没有接触过网管交换机的话,你可能会觉得奇怪:这不是二层设备么,为什么会有IP地址?你需要在vlanif上配置它,有关详细信息,你可以参阅这里:

vlanif和vlan的区别

交换机要ip有什么用? – 知乎

VLAN_LAB_8.png

接下来我们该来配置一下VLAN了。根据要求,把Ethernet 0/0/3包含到VLAN 2中,把Ethernet 0/0/4包含到VLAN 3中:

VLAN_LAB_9.jpg
摘自文档
VLAN_LAB_10.jpg
接口Ethernet0/0/03划分至VLAN 2

在VLAN中添加端口也是可行的。

如果遇到问题需要更改端口类型:

VLAN_LAB_11.png

如果你不明白,我想你应该去搜索一下有关trunk/access/hybrid的内容。

另一个接口同理,都配置好之后应该能看到是这样的:

VLAN_LAB_12.jpg
display vlan

这个时候就可以开始测试了:

VLAN_LAB_13.jpg
10.110.10.1发送ping至10.110.10.2

如果目标主机的防火墙默认阻挡ICMP协议的封包,请根据实际情况修改策略,例如接受局域网的ICMP封包,或者完全接受。你也可以为不联网的、与其它局域网隔离的实验的PC关闭防火墙。如果你不事先进行检查,这会影响到实验的结果。

由于两个PC被分配到了不同的VLAN中,并且没有可达路由,所以它们不能互相通信。这个时候,我们切换到Xshell中更改VLAN划分。由于刚刚的ping带有-t参数,它会不停地继续发送ping包。我们来把Ethernet 0/0/4改到VLAN2中看看:

VLAN_LAB_14.jpg
更改至同一VLAN后即可正常通信

我们刚把Ethernet 0/0/4添加到VLAN2后马上可以看到这边已经可以ping通了。

Trunking

希望你在搞这个之前已经清楚地知道自己在做什么…如果不知道的话,我觉得你可以尝试着去搜一下相关的内容,也可以看看单线复用、单臂路由之类的应用,或许能有所帮助,而且说不定就能在日常生活中用起来了呢?

我们先把之前创建的VLAN先都删掉:

VLAN_LAB_15.png
去掉刚刚设置的VLAN

这个时候还是接线,按照PPT说明接好:

VLAN_LAB_16.png

由于这个交换机的22好像是坏的…于是换到了20上(真是尴尬)。所以我们接下来要干的事情是:

  1. 将PC1连接到交换机1的Ethernet 0/0/3上,配置静态IP为10.110.10.1/24;
  2. 将PC2连接到交换机1的Ethernet 0/0/12上,配置静态IP为10.110.10.2/24;
  3. 将PC3连接到交换机2的Ethernet 0/0/13上,配置静态IP为10.110.10.3/24;
  4. 将PC4连接到交换机2的Ethernet 0/0/20上,配置静态IP为10.110.10.4/24;
  5. 找根网线把交换机1的Ethernet 0/0/23和交换机2的Ethernet 0/0/23连接起来。

大概会是这个样子:

VLAN_LAB_17.png

接下来继续回到Xshell上开始配置交换机,我们先来折腾交换机1:

  1. 将Ethernet 0/0/3添加到VLAN 3中;
  2. 将Ethernet 0/0/12添加到VLAN 2中;
  3. 将Ethernet 0/0/23配置为trunk并允许VLAN 2/3的流量通过。

这台交换机的端口就不像想象中的那样了:

VLAN_LAB_18.png
端口和另一台不大一样

这里是GigabitEthernet0/0/1

这里添加各端口到VLAN中的命令大家应该都清楚了,不再挂图了…看看trunk:

VLAN_LAB_19.png

别忘了还要允许流量通过:

VLAN_LAB_20.png

是不是又想说和PPT里不一样?可是官方文档里可是清清楚楚地只有上面图里那种用法的哦。自己动手,丰衣足食吧。

VLAN_LAB_21.png

检查过没有问题了就可以继续配置交换机2了:

  1. 将Ethernet0/0/13添加到VLAN 3中;
  2. 将Ethernet0/0/20添加到VLAN 2中;
  3. 将Ethernet0/0/23配置为trunk并允许VLAN 2/3的流量通过。

跟上面差不多,我就不累死累活上图了。如果两台都配置好了之后就可以来测试了!根据实验要求:

PC1和PC2之间能否ping成功:

VLAN_LAB_22.png

由于PC1和PC2不在同一个VLAN,并且不存在可达路由,所以不能ping通。

PC1和PC3之间能否ping成功:

VLAN_LAB_23.png

PC1和PC3在同一个VLAN中,并且配置好了trunk,可以ping通。

PC2和PC4之间能否ping成功:

VLAN_LAB_24.png

同一VLAN,并且有正确的trunk,可以ping通。

附加一个PC2和PC3:

VLAN_LAB_25.png

大概这样子就圆满完成了。不过走之前别忘了删掉VLAN,网线插回原位之类的扫尾工作哈。

控制台记录

最后附一些控制台记录,仅供参考,并且有我瞎玩的记录。请务必记得看文档。

<Quidway>system-view 
[Quidway]interface Vlanif 2
Error: The VLAN does not exist.
[Quidway]vlan 2 
[Quidway-vlan2]quit
[Quidway]interface Vlanif 2
[Quidway-Vlanif2]ip address 10.110.10.3 255.255.255.0
[Quidway]undo vlan 2
Error: The VLAN has a L3 interface. Please delete it first.
[Quidway]vlan 2 
[Quidway-vlan2]port Ethernet0/0/3
Error: Trunk or Hybrid port(s) cannot be added or deleted in this manner.
[Quidway]interface Ethernet0/0/3
[Quidway-Ethernet0/0/3]port link-type access
[Quidway-Ethernet0/0/3]port default vlan 2
[Quidway-Ethernet0/0/3]display vlan 2
* : management-vlan
---------------------
VLAN ID Type         Status   MAC Learning Broadcast/Multicast/Unicast Property 
--------------------------------------------------------------------------------
2       common       enable   enable       forward   forward   forward default  
----------------
Untagged   Port: Ethernet0/0/3               
----------------
Interface                   Physical 
Ethernet0/0/3               UP      
[Quidway]interface GigabitEthernet0/0/23
[Quidway-GigabitEthernet0/0/23]port link-type trunk
[Quidway-GigabitEthernet0/0/23]port trunk allow-pass vlan all