[转]编译预处理之头文件包含妙用
晚上看见这篇文章,感觉有点意思,就转了给大家,原文地址:http://www.,以下内容跟原文基本相同。-----------------------------------------------------------------------------------------------------------------------------------------------------
今天突发奇想,想弄个用纯C编写一个简单的网络程序(呵呵!对C语言情有独钟),通过调用Windows API函数来实现网络通讯。编译环境为Dev-C++。
网上找啊找啊,参考了一些C++程序通过调用WindowsAPI函数来实现网络通讯,实在复杂,那些代码看得我头都晕,好不容易才理清思路,花了我九牛二虎之力才成功把这些程序从VC++移植到纯C环境下,但想了一会儿,感觉这样还是不太好,虽然现在没时间编程(要应付高考啊~~~),但到了有时间编写程序的是时候不就要把这些程序重新弄懂再写,太浪费时间啦~~~~
怎样解决这个问题?今天突发奇想,运用C语言编译预处理的文件包含。下面是以个示例程序。
network.h头文件,内容如下:
//初始化WINSOCK库
//在使用WinSock库函数时,必须先初始化该程序。
WSADATA netData;
int netStatus;
netStatus=WSAStartup(MAKEWORD(2, 1), &netData);
if (netStatus != 0)
{
printf("出错了: WSAStartup 调用失败\n");
return 0;
}
cliconn.h头文件,内容如下:
//客户端初始化
//连接指定IP地址。在此头文件前加上 #define DEST_IP_ADDR "127.0.0.1" 的语句即可。
//连接指定端口。在此头文件前加上 #define PORT (u_short) 12345 的语句即可。
//设置缓冲区大小。在此头文件前加上 #define cliMAXBUF 256 的语句即可。
//标识一台服务器的地址端口的结构体
SOCKADDR_IN cliDestSockAddr;
//用于收发信息的客户端套接字
SOCKET cliDestSocket;
//状态显示变量
int cliStatus;
//发送的数据的大小
int clinumsnt;
//接收数据的大小
int clinumrcv;
//存放发送到服务器端的信息的缓冲区
char cliSendText[cliMAXBUF];
//存放从服务器端接收到的信息的缓冲区
char cliRecvText[cliMAXBUF];
//把"."分隔的IP字符串转换成IP地址赋予给SOCKADDR_IN结构体
//中的in_addr结构体里的s_addr变量,以后就这样用就行
cliDestSockAddr.sin_addr.s_addr = inet_addr(DEST_IP_ADDR);
//把服务器程序上的正整数端口号转换成网络地址格式赋予给
//SOCKADDR_IN结构体的sin_port变量
cliDestSockAddr.sin_port=htons(PORT);
//下面这个不用知道有什么用,知道必须要这样就行
cliDestSockAddr.sin_family=AF_INET;
//创建一个套接字进行连接到服务段程序上
cliDestSocket=socket(AF_INET, SOCK_STREAM, 0);
if (cliDestSocket == INVALID_SOCKET)
{
printf("出错了: socket 函数调用失败\n");
WSACleanup();//释放WINSOCK库
return 0;
}
//连接到服务器程序
cliStatus=connect(cliDestSocket,
(LPSOCKADDR) &cliDestSockAddr,
sizeof(cliDestSockAddr));
if (cliStatus == SOCKET_ERROR)
{
printf("出错了: connect 调用失败\n");
closesocket(cliDestSocket);//关闭套接字
WSACleanup();
return 0;
}
memset(cliSendText,0,cliMAXBUF);
memset(cliRecvText,0,cliMAXBUF);
cliSend.h头文件,内容如下:
//客户端发送数据
//给服务端发信息。在此头文件前给 cliSendText 字符串变量赋值即可
//变量说明:
//存放发送到服务器端的信息的缓冲区:char cliSendText[cliMAXBUF];
// printf("请输入要发送的文本数据: ");
// gets(cliSendText);
//把数据发送到服务器程序
clinumsnt=send(cliDestSocket, cliSendText,
strlen(cliSendText) + 1, 0);
if (clinumsnt != (int)strlen(cliSendText) + 1)
{
printf("连接已经断开了.\n");
closesocket(cliDestSocket);
WSACleanup();
return 0;
}
cliGet.h头文件,内容如下:
//客户端接受数据
//从服务端接受信息。在此头文件后获取 cliRecvText 字符串变量即可
//变量说明:
//存放发送到服务器端的信息的缓冲区:char cliSendText[cliMAXBUF];
clinumrcv=recv(cliDestSocket, cliRecvText,
cliMAXBUF, 0);
if ((clinumrcv == 0) || (clinumrcv == SOCKET_ERROR))
{
printf("连接已经断开了.\n");
closesocket(cliDestSocket);
WSACleanup();
return 0;
}
// printf("从服务器端接收的信息:%s\n",cliRecvText);
好了,就是这4个头文件,用于实现连接指定服务器IP和端口,然后发送信息。这时,我没就可以这样写主程序了。如下代码:
#include <stdio.h>
#include <stdlib.h>
#include <winsock.h>
#include <windows.h>
int main(int argc, char *argv[])
{
#include <D:\User\Local-PC\桌面\temp\C\NetFunctions\network.h>
#define DEST_IP_ADDR "127.0.0.1"
#define PORT (u_short) 12345
#define cliMAXBUF 256
#include <D:\User\Local-PC\桌面\temp\C\NetFunctions\cliConn.h>
while(1)
{
printf("请输入要发送的文本数据:");
gets(cliSendText);
#include <D:\User\Local-PC\桌面\temp\C\NetFunctions\cliSend.h>
}
system("PAUSE");
return 0;
}
程序在Windows XP sp3、Dev-C++环境下编译通过。注意这个程序需要在Dev-C++中,project->project options -> parameters, 在 linker框中输入 "-lwsock32" (注意:无引号)才能编译通过。
呵呵,是不是感觉简单很多,当然,上面的头文件写得还是不够完善的,但这里提供的一种思维方式、一种灵感、一种手段,我们再日常写程序的时候就可以把常用的程序写入头文件或函数中,需要时,只需几句调用代码,就可以完成需要写几十行代码才能完成的功能,还可以通过各位程序员共用代码(做人要厚道啊,别写入一些恶意代码啊~~~),真是节省了大量开发时间,好了,今天就写到这,快去建立属于你自己的代码库吧~~~
-----------------------------------------------------------------------------------------------------------------------------------------