JAVA 网络编程实验报告
学院:
班级:
学号:
姓名:
指导老师:
一. 实验题目
用 winpcap 编程实现一个 UDP 发送端,java 编程实现接收
端。Ethereal 抓包工具也能抓到 UDP 包。
二. 实验环境
安装了 winpcap,并进行了相关配置,在 VC6.0 上实现。Java 方
面安装了 jpcap,进行相关配置,利用 jpcap 进行抓包,在 eclipse
上实现。
三. 实验内容
1.抓包
首先用程序发送一个 UDP 数据包,用 Ethereal 抓到此包,
如图:
我的学号是 0907300321,因此源 IP 地址是 192.168.3.21。本机的
IP 是 192.168.0.12。此包发送的源端口是 3368,目的端口是 21。
2.分析 MAC 头
MAC 源地址是 03:02:01(学号 0907300321),目的地址是 3b:71:66。
类型是 0x0800。
3.分析 IP 头
IP 版本为 4。IP 头长度为 20 字节。协议是 UPD(0x11)。源 IP
是 192.168.3.21。目的 IP 是 192.168.0.12。IP 检验和是 0x30cd。
IP 检验和的计算方法如下:
checksum 的计算是用除了校验和外的 IP 头部的所有字段的值相
加然后求反码所得,计算中要注意加上进位。为了计算一份数据
报的 IP 检验和,首先把检验和字段置为 0.然后,对首部中每个
16bit 进行二进制反码求和,(整个首部堪称是由一串 16bit 的字
组成),结果存在检验和字段中。当收到一份 IP 数据报后,同样
对首部中每个 16bit 进行二进制反码的求和。由于接收方在计算
过程中包含了发送方存在首部中的检验和,因此,如果首部在传
输过程中没有发生任何差错,那么接收方计算的结果应该是全 1,
如果结果不是全 1(即检验和错误),那么 IP 就丢弃收到的数据
包。但是不生成差错报文,由上层去发现丢失的数据报并进行重
传。
下面结合实际数据进行计算:
计算除校验和以外的和数:
Sum1=4500+0032=4532;
Sum2=Sum1+047d=49af;
Sum3=Sum2+0000=Sum2
Sum4= Sum2+0111=4ac0;
Sum5= Sum4+c0a8=0b68;这里进位为 1;
Sum6= Sum5+0315=0e7d;
Sum7=Sum6+c0a8=cf25;
Sum8=Sum7+000c=cf31;
Sum9=cf31+0001= cf32;这里 0001 是计算 Sum5 时的进位 1。
因 此 , 校 验 和 要 对 Sum9 求 补 码 , 即 校 验 和
checksum=ffff-cf32=30cd。
4.分析 UDP 头
UDP 包发送的源端口是 3368,目的端口是 21。检验和是 a907。
四. 用 winpcap 实现 UDP 发送端,Java 编程实现接收端
Winpcap 源代码如下:
#include
#include
#include
void usage();
int main(int argc, char **argv) {
pcap_t *fp;
char error[PCAP_ERRBUF_SIZE];
u_char
packet[65]={0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x02,0x01,0x3b,0x7
1,0x66,0x08,0x00,
0x45,0x00,0x00,0x32,0x04,0x7d,0x00,0x00,0x01,0x11,0x30,0xc
d,0xc0,0xa8,0x03,0x15,0xc0,0xa8,0x00,0x0c,
0x0d,0x28,0x00,0x15,0x50,0x5f,0xa9,0x07,0x4b,0x4f,0x45,0xc
2,0x50,0x10,0x40,0xb0,0x5b,0x1c,0x00,0x00,0x4b,0x4f,0x45,0xc2,
0x50,0x10,0x40,0xb2,0x28,0x6c,0x22};
pcap_if_t *alldevs;
pcap_if_t *d;
int inum;
int i=0;
pcap_t *adhandle;
char errbuf[PCAP_ERRBUF_SIZE];
/* Check the validity of the command line */
if (pcap_findalldevs(&alldevs, errbuf) == -1)
{
}
fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);
exit(1);
/* 打印网卡信息 */
for(d=alldevs; d; d=d->next)
{
}
printf("%d. %s", ++i, d->name);
if (d->description)
printf(" (%s)\n", d->description);
else
printf(" (No description available)\n");
if(i==0)
{
printf("\nNo interfaces found! Make sure WinPcap is
installed.\n");
return -1;
}
printf("Enter the interface number (1-%d):",i);
scanf("%d", &inum);
//输入要选择
打开的网卡号
if(inum < 1 || inum > i)
//判断号的合法性
{
}
printf("\nInterface number out of range.\n");
/* Free the device list */
pcap_freealldevs(alldevs);
return -1;
/* 找到要选择的网卡结构 */
for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++);
/* 打开选择的网卡 */
if((fp = pcap_open_live(d->name, 100, 1, 1000, error) ) ==
NULL)
{
fprintf(stderr,"\nError opening adapter: %s\n", error);
return;
}
/* 发送包 */
pcap_sendpacket(fp,
packet,
65);
return;
}
运行结果如下:
Jpcap 源代码如下:
import java.io.IOException;
import jpcap.JpcapCaptor;
import jpcap.PacketReceiver;
import jpcap.packet.IPPacket;
import jpcap.packet.Packet;
public class JpcapCeshi