实验八:网络管理
任务1:编写基于socket的udp发送接收程序
-
编写C源码,基于socket的udp发送接收程序,实现客户端与服务端的简单通信。
-
客户端从命令行输入中读取要发送的内容,服务端接收后实时显示。
client.c
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#define PORT 40000
#define BUF_SIZE 1024
int main(void)
{
int sock_fd;
char buffer[BUF_SIZE];
int size;
int len;
int ret;
struct sockaddr_in server_addr;
if(-1 == (sock_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP)) ){
printf("Failed to create a socket!\n");
return 0;
}
//server infomation
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(PORT);
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
bzero(buffer, BUF_SIZE);
len = sizeof(server_addr);
//read from stdin and send to server
while(1){
printf("Please enter the content to be sent:\n");
size = read(0, buffer, BUF_SIZE);
if(size){
sendto(sock_fd, buffer, size, 0, (struct sockaddr*)&server_addr, len);
bzero(buffer, BUF_SIZE);
}
}
close(sock_fd);
return 0;
}
server.c
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#define PORT 40000
#define BUF_SIZE 1024
int main(void)
{
int sock_fd;
int len;
char buffer[BUF_SIZE];
struct sockaddr_in server_addr, client_addr;
if(-1 == (sock_fd = socket(AF_INET, SOCK_DGRAM, 0)) )
{
printf("Failed to create a socket!\n");
return 0;
}
//server information
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(PORT);
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
if(-1 == bind(sock_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)))
{
printf("Failed to bind the socket!\n");
return 0;
}
len = sizeof(client_addr);
//rec and print
while(1)
{
bzero(buffer, BUF_SIZE);
if(-1 != (recvfrom(sock_fd, buffer, BUF_SIZE, 0, (struct sockaddr*)&client_addr, &len)) )
{
printf("The message received is: %s", buffer);
}
}
return 0;
}
内核模块加载结果
编译
客户端:
服务端:
任务2:使用 tshark 抓包
tshark是wireshark中提供的Linux命令行工具,tshark不仅有抓包的功能,还带了解析各种协议的能力。由于wireshark的运行需要GUI(图形用户界面,Graphical User Interface)的环境,但是树莓派openEuler系统的缺省安装是不含GUI的,此时就可以使用tshark进行抓包。
安装:
yum install wireshark
基于任务1的服务端与客户端程序运行时,使用tshark抓取该通信数据包。
抓包流程
1、先用 ifconfig查看网卡信息
2、分别在3个终端运行不同的程序
终端1:运行客户端
终端2:运行服务端
终端3:运行抓包程序
tshark -i lo -n -f 'udp port 40000'#直接把抓包结果输出到命令行
任务3:使用 setsockopt 发送记录路由选项
-
基于任务1的客户端与服务端,使用setsockopt发送一个带IP记录路由选项的数据包;
-
使用tshark查看发送的数据包中是否包含了记录路由选项。
client.c
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#define PORT 40000
#define BUF_SIZE 1024
int main(void)
{
int sock_fd;
char buffer[BUF_SIZE];
char rrbuf[28];
int size;
int len;
int ret;
struct sockaddr_in server_addr;
if(-1 == (sock_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP)) ){
printf("Failed to create a socket!\n");
return 0;
}
//server infomation
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(PORT);
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
bzero(buffer, BUF_SIZE);
len = sizeof(server_addr);
//read from stdin and send to server
while(1){
printf("Please enter the content to be sent:\n");
size = read(0, buffer, BUF_SIZE);
if(size){
bzero(rrbuf,sizeof(rrbuf));
rrbuf[0] = 0x07;
rrbuf[1] = sizeof(rrbuf) - 1;
rrbuf[2] = 4;
rrbuf[sizeof(rrbuf) - 1] = 0;
ret = setsockopt(sock_fd,IPPROTO_IP,IP_OPTIONS,(void*)rrbuf,sizeof(rrbuf));
if(-1 == ret){
printf("setsockopt error!\n");
return 0;
}
sendto(sock_fd, buffer, size, 0, (struct sockaddr*)&server_addr, len);
bzero(buffer, BUF_SIZE);
}
}
close(sock_fd);
return 0;
}
server.c ——同任务1
运行结果
客户端
服务端
抓包程序
tshark -i lo -n -f 'udp port 40000' -T pdml > ./res.xml #把抓包结果以指定格式输出到指定文件中
在重定向的 setsockopt.xml 文件中,可看到如下记录路由内容