当前位置:  编程技术>c/c++/嵌入式
本页文章导读:
    ▪C语言实现wake on lan(网络唤醒)              wake on lan是一种网络唤醒功能,它可以实现远程开机,刚好实验室有一台ftp服务器,因为不是24小时开机的,所以每次开机都要跑过去用手按开关,非常麻烦,于是在网上.........
    ▪Windows系统下用命令行编译C/C++程序过程总结      前一段时间在自学linux系统,想模仿linux命令行的方式在Windows下编译C/C++程序,摸索一段时间后总算把这个解决了!(1)先用记事本编写如下所示的代码,并另存为hello.cpp,假设其保存路径为C.........
    ▪字符串常量引起的思考        记得以前看过一道这样的题目:  以下程序的执行结果是?#include <stdio.h> int main(){ char* p="Hello World"; *(p+1)='a'; printf("%s\n",.........

[1]C语言实现wake on lan(网络唤醒)
    来源:    发布时间: 2013-10-14

        wake on lan是一种网络唤醒功能,它可以实现远程开机,刚好实验室有一台ftp服务器,因为不是24小时开机的,所以每次开机都要跑过去用手按开关,非常麻烦,于是在网上找了下资料,自己实现了一把,并在windows下用Qt写了个简单的界面,以后想开服务器就方便了。原理就是源主机广播一个特殊的数据包给目的主机,前提是目的主机的主板支持wake on lan并在BIOS里已经设置好,还有就是要知道目的主机的MAC地址。这个特殊的数据包叫做magic packet,它由102个字节组成,最前面六个字节为0xFF,其他字节为目的主机的MAC地址(6个字节为一组,共16组),如下图所示:

 

       知道这个原理之后就可以很容易实现了,实现代码如下,本人亲测。

1 #include <stdio.h>
2 #include <arpa/inet.h>
3 #include <sys/ioctl.h>
4 #include <net/if.h>
5 #include <string.h>
6 #include <unistd.h>
7 #include <stdlib.h>
8
9
10 int main(int argc, char* argv[])
11 {
12 unsigned char mac[6]={0x00,0x10,0x20,0x30,0x40,0x50};//目的主机MAC地址,例如: 00:10:20:30:40:50
13 unsigned char packet[102];
14 struct sockaddr_in addr;
15 int sockfd, i,j, on = 1;
16
17 //构建magic packet
18 for(i=0;i<6;i++)
19 packet[i] = 0xFF;
20
21 for(i=1;i<17;i++)
22 for(j=0;j<6;j++)
23 packet[i*6+j] = mac[j];
24
25 //UDP
26 sockfd = socket(AF_INET, SOCK_DGRAM, 0);
27 //广播
28 setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST,&on, sizeof(on));
29 if(sockfd < 0)
30 exit(0);
31
32 memset((void*)&addr, 0, sizeof(addr));
33 addr.sin_family = AF_INET;
34 addr.sin_port = htons(10000);
35 addr.sin_addr.s_addr = inet_addr("xxx.xxx.xxx.xxx");//广播地址
36
37 sendto(sockfd, packet, sizeof(packet), 0, (struct sockaddr *)&addr, sizeof(addr));
38 close(sockfd);
39
40 return 0;
41 }

实际中需要根据目的主机来修改MAC地址和广播地址。

 

 

本文链接


    
[2]Windows系统下用命令行编译C/C++程序过程总结
    来源:    发布时间: 2013-10-14

前一段时间在自学linux系统,想模仿linux命令行的方式在Windows下编译C/C++程序,摸索一段时间后总算把这个解决了!

(1)先用记事本编写如下所示的代码,并另存为hello.cpp,假设其保存路径为C:\Users\Administrator\Desktop。

#include<iostream>

using namespace std;

int main()

{

    cout<<"hello world!"<<endl;

    return 0;

}

(2)用记事本写一段简单的批处理文件,内容如下所示,在保存文件时选择另存为,文件名假设为batch.bat,bat是批处理文件的后缀,保存类型选择:所有文件(这个尤其需要注意),假设其保存路径也是C:\Users\Administrator\Desktop。

set path=D:\Softwares\en_Visual_Studio2010_Professional_x86_x16-81637\VC\bin

set include=D:\Softwares\en_Visual_Studio2010_Professional_x86_x16-81637\VC\include

set lib=D:\Softwares\en_Visual_Studio2010_Professional_x86_x16-81637\VC\lib

上面批处理文件的第一句话表示设置环境变量,这个也可以通过:计算机/属性/高级系统设置/环境变量/用户变量,D:\Softwares\en_Visual_Studio2010_Professional_x86_x16-81637\VC\bin放到path的值里去,记得与之前已有值之间用";"隔开。这个path文件夹是我们装载VS2010时自带的,在设置路径时要根据自己的安装路径进行修改,里面包含微软在Windows下给我们提供的C/C++编译器cl.exe程序(编译器自身也是一个软件程序,只是它的作用是用来编译其它的程序),当然还有link.exe链接程序,调用cl时,系统会自动调用link程序(后面将看到我们只用了cl命令就可以进行C/C++程序的编译、链接)。后面两句话分别表示包含C++中自带的头文件库和静态链接库,静态理解库包含了头文件中函数对应的实现部分,为了不让人们看到其中的源代码,它以二进制文件形式编码,若要查看其内容需要进行反汇编。

(3)通过cmd命令进入DOS操作界面,输入cd C:\Users\Administrator\Desktop进入cpp文件和bat批处理文件所在的位置,然后键入batch.bat进行批处理,这些操作在VS2010集成开发环境中都为我设置好了,所以我们在里面写C/C++程序时并没有这样设置路径的繁琐操作,但是通过自己手动的路径设置,我们会对程序的编译、链接、执行有更加深入的认识。

(4)键入cl hello.cpp,我们会看到计算机报出了“无法启动此程序,因为计算机中丢失mspdb100.dll。尝试重新安装该程序以解决此问题”的系统储物,dll文件是动态链接库文件,其是在cl.exe程序运行时才被加载进来的文件,这个静态链接库lib文件不同。这说明在D:\Softwares\en_Visual_Studio2010_Professional_x86_x16-81637\VC\bin路径里没有找到mspdb100.dll,原来此文件在文件夹D:\Softwares\en_Visual_Studio2010_Professional_x86_x16-81637\VC\Common7\IDE里,我们可以将此文件拷到bin文件夹里,或将D:\Softwares\en_Visual_Studio2010_Professional_x86_x16-81637\Common7\IDE加到批处理的path环境变量里,或者将其加到cpp文件所在的文件夹里,这只会引起在搜索顺序上的不同。

(5)再次键入cl hello.cpp,我们看到在C:\Users\Administrator\Desktop文件夹里得到了hello.obj文件,这是编译后的输出文件,但是没有得到可执行exe文件,DOS界面里出现这样的错误“LINK:fatal error LNK1104:cannot open file 'kernel32.lib' “这样的链接错误,kernel32.lib是Windows系统文件,通过Windows自带的搜索工具,我们看到此文件在文件夹C:\Program Files\Microsoft SDKs\Windows\v7.0A\Lib里,我们可以将其加到cpp文件所在的文件夹或bin文件里。再次键入cl hello.cpp,我们发现这次程序被成功编译链接了,cpp文件所在的文件夹里多了两个文件:hello.obj和hello.exe。

(6)在DOS界面键入hello.exe,程序被执行,输出了我们预想的hello world!,至此,在Windows下模拟linux命令行操作,编译C/C++文件全部完成了。

本文链接


    
[3]字符串常量引起的思考
    来源:    发布时间: 2013-10-14

  记得以前看过一道这样的题目:

  以下程序的执行结果是?

#include <stdio.h>

int main()
{
char* p="Hello World";
*(p+1)='a';
printf("%s\n",p);
return 0;
}

  应该不难吧,不知道大家的答案是什么。

  以下是我的一些解答:

    对于指针p,他的大小是sizeof(char),那么在哪里存放字符串“Hello World”呢?

    我们知道,程序编译时,编译器将代码翻译成汇编代码,然后汇编器将汇编代码翻译成机器代码(得到目标文件),最后链接器将目标文件链接成可执行文件。

  而目标文件和可执行文件的格式一般是类似的,由一个个section(段)组成,一般来说有代码段、数据段、bss段等,有些平台还会有.rodata段(只读数据段),用来

  放置只读变量(const变量)和字符串常量,这样不仅可以在语义上支持C++的const,而且操作系统还可以在加载的时候将.rodata映射为只读,这样对于这个段的修改

  会作为非法处理,保证了程序的安全。

  (1)在Linux下可以用objdump查看目标文件或可执行文件中的内容:  

objdump -x -s -d testchar

  得到的结果如下:

  

  (左边是十六进制内容,右边是ASCII形式的内容)

  可以看到字符串Hello World就在.rodata段中。

 

  (2)接下来我们使用readelf来查看.rodata段的属性:

    

  得到:

  

  其中.rodata段的标志(Flg)为A(alloc),表示该段在进程中要分配空间,如果一个段可写的话,应该要有W(write)标志,如数据段(.data):

    

  也就是说,现在字符串“Hello World”在不可写的.rodata中,如果我们用指针直接修改的话,就会引发段错误。

  所以程序的运行结果是:Segmentation fault

 

  (3)数组中的情况

  如果程序是这样呢:

#include <stdio.h>

int main()
{
char p[]="Hello World";
*(p+1)='a';
printf("%s\n",p);
return 0;
}

  程序是可以正常运行的。

  同样用objdump查看.rodata的内容:

  

  发现字符串已经不在.rodata中了。

  对于数组,我们可以直接分配空间,像上面的数组p就可以直接在栈中分配空间来存放字符串“Hello World”,这样就可以修改字符串了。

 

  以下内容我有点不肯定:

  查看text段(代码段)中的内容,发现字符串在text段中。

  

  所以我的猜想是程序执行时,先将text段中的字符串复制到数组p在栈中的分配的内存里,这样就可以对字符串修改同时又不影响代码段中的内容(因为代码段一般是只读的)

  不知我这个猜想对不对,希望各位解答一下……

本文链接


    
最新技术文章:
▪C++单例模式应用实例
▪C++设计模式之迭代器模式
▪C++实现动态分配const对象实例
▪C++设计模式之中介者模式
▪C++设计模式之备忘录模式
▪C++插入排序算法实例
▪C++冒泡排序算法实例
▪C++选择排序算法实例
▪C++归并排序算法实例
▪C++设计模式之观察者模式
▪C++中复制构造函数和重载赋值操作符总结
▪C++设计模式之状态模式
▪C++设计模式之策略模式
▪C++设计模式之访问者模式
▪C++设计模式之模板方法模式
▪C++实现下载的代码
▪C++模板之特化与偏特化详解
▪C++实现查壳程序代码实例
▪C语言、C++内存对齐问题详解
▪C语言、C++中的union用法总结
▪C++基于CreateToolhelp32Snapshot获取系统进程实例
▪C++中memcpy和memmove的区别总结
▪C++通过TerminateProess结束进程实例
▪C++内存查找实例
▪C++实现CreatThread函数主线程与工作线程交互的...
▪C++设计模式之桥接模式
▪C++中关键字Struct和Class的区别
▪C++设计模式之组合模式
▪C++ COM编程之什么是组件?
▪C++ COM编程之什么是接口?
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3