1、编写基于socket的udp发送接收程序
本次实验与计算机网络实验课程内容有重叠,因为之前做过windows下的socket编程,掌握了代码思路,所以本次实验的代码也相对比较容易理解。
TCP/IP协议族:
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");//本机默认IP地址
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;
}
gcc命令编译运行:
打开两个终端,客户端发消息、服务端实时接收消息:
客户端:
服务端:
2、使用 tshark 抓包
ifconfig命令查看网卡配置信息:
使用本机的lo接口:
tshark -i lo -n -f 'udp port 40000' //直接把抓包结果输出到命令行
tshark -i lo -n -f 'udp port 40000' -T pdml > /root/task2.xml //把抓包结果以指定格式输出到指定文件中
打开三个终端,分别作为客户端、服务端以及运行抓包程序:
客户端:
服务端:
运行抓包程序:
出错,找不到命令,原因是未安装wireshark,所以使用dnf安装,又出错,提示未找到包:
说明所配置的yum源中没有该包,方便起见,使用自带的tcpdump命令进行抓包,也能达到理想效果:
可以看到抓包程序抓取到4个本地回环网络的包,就是客户端发给服务端的4条字符串。
3、使用 setsockopt 发送记录路由选项
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:
#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;
}
编译、测试:
-
客户端:
-
服务端:
-
抓包程序:
-
查看抓包保存的文件:
可以看到,抓取到了四条从客户端发送到服务端的消息以及其余信息。