Windows 下 C 语言网络编程快速入门
作者:未知 文章来源:天极网 点击数: 7623 更新时间:2004-9-25
C 语言的学习,一般的方式是,先学 C,然后是 C++,最好还要
有汇编语言和微机原理基础,然后才是 Visual C++。这样的方式,对
学习者来说,要花费很多时间和耐力。而在学校教学中,也没有时间深
入学习 Windows 编程的实用技术了。
其实,具有了 C 语言基础后,再有一些基本的 C++类的概念,就可以直接学习 Windows C 编程
了。
一、走近 Windows C 语言
很多语言都把显示一个“Hello,World!”做为第一个入门程序, C 语言的第一个程序是这样的:
#include<stdio.h>
main()
{
printf(“Hello,World!”);
}
如果把 main 函数写成带参数的 main 函数,应该是:
#include<stdio.h>
main(int arge,char *argv[])
{
printf(“Hello,World!”);
[文章导读]
只要有了 C++类的基本概念,那么 C 语
言的初学者也能进行 Windows 网络编程
}
Windows C 的第一个程序和这个程序在形式和原理上都是一致的,只是有两点不同:
1. 主函数接收的形参不只是命令行中的字符串的个数和字符串的首地址。
2. C 语言的很多函数在 Windows C 中都可以继续使用,但象 printf()屏幕显示等函数就不能继续使用了。因
为 Windows 是多任务操作系统,屏幕已不再为某一个应用程序所独有,Windows C 应用程序要显示字符串,需要
使用 Windows 提供的 API 函数,开自己的窗口
下面是一个最简单的,显示“Hello,World!”的 Windows C 程序:
#include<windows.h>
APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,
LPSTR lpCmdLine,int nCmdShow)
{
MessageBox(NULL,"Hello,World!","第一个 Windows C 程序",MB_OK|MB_ICONASTERISK);
}
主函数的形参有四个:
1) Hinstance:接收程序运行时当前实例的句柄;
2) HprivInstance:前一个实例的句柄;
3) LpCmdLine:程序命令行指针;
4) NcmdShow:一个用来指定窗口显示方式的整数。
这几个参数的使用我们会在深入的学习中介绍的。
显示 Hello,Word!字符串,我们使用了一个 MessageBox 函数,这个函数会在屏幕上显示一个对话框,它的原型
是:
int MessageBox(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaption,UNIT uType)
四个参数分别是:
1) HWnd:父窗口的句柄;
2) LpText:要显示字符串的指针;
3) LpCaption:对话框标题字符串的指针;
4) UType:显示在对话框上的小图标的类型。
使用这个函数要包含 windows.h 头文件。
调试一下,怎么样?窗口上弹出了一个“第一个 Windows C 程序”对话框,上面有一行字:“Hello,World!”。
世界真的很美好啊!!
深入编程:
在 C 语言中,函数的声明,如果没有指明返回值类型,缺省值为 void,这个程序的主函数就没有返回值。不过,
在 Windows 编程时,我们最好养成个好习惯,指明函数的返回值类型,因为在 C++中,函数返回值类型是不可以缺
省的。而我们在 Windows C 编程时,还是会用到 C++的一些概念,这样做,有利于以后深入地学习。
规范一点的程序应该是这样的:
#include<windows.h>
int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,
LPSTR lpCmdLine,int nCmdShow)
{
MessageBox(NULL,"Hello,World!","第一个 Windows C 程序",MB_OK|MB_ICONASTERISK);
return 0;
}
这里,我们声明的类型为 int 型,并且返回一个值 0,这样的函数就可以使用在复杂一点的函数调用中了。
在这一节中,我们有几处都提到了句柄的概念,句柄和指针的概念不同,它是作为操作系统内部索引表中的一个
值来使用的,这样可以防止应用程序直接访问名对象的内部结构,体现了 Windows 资源管理的优越性。譬如说,一
个窗口找开之后,好对应内存中的一个内存块,这个窗口所在的内存快地址往往会由操作系统做动态的调整,但其却
不会随之变化。不过,通过它可以访问这个窗口,所以在使用的时候,可以把它当做指针一样看待。
二、 获取本地计算机的主机名和 IP 地址
和 C 语言一样,函数是 Windows C 编程的最基本的单位。不过,Windows C 主要使用 API 函
数,而网络编程则主要使用 Winsock 提供的 API 函数。
Winsock 是 90 年代初,为了方便网络编程,由 Microsoft 联合了其他几家公司共同制定的一套
WINDOWS 下的网络编程接口,它是通过 C 语言的动态链接库方式提供给用户及软件开发者的,主要
由 winsock.h 头文件和动态链接库 winsock.dll 组成,目前有两个版本:Winsock1.1 和
Winsock2.0。
在 Win32 平台上,访问众多的基层网络协议,Winsock 是首选接口。
用 Visual C++6.0 编译 Windows C 程序,使用 Winsock API 函数时,首先要把 wsock32.lib
添加到它的库模块中,否刚在链接的时候,会出现“error LNK2001”错误。添加 wsock32.lib 的具体
步骤是:打开工程菜单,选择设置,在弹出的 Project settings 对话框中,点击 link 选项卡,然后在
对象/库模块文本框中添加 wsock32.lib。
最简单的网络编程是获取本机的主机名和 IP 地址,这个程序使用了
WSAStart()、WSAClenaup()、gethostname()、gethostbyname()四个 winsock API 函
数,这四个函数的功能和使用方法介绍如下:
1. WSAStartup():
【函数原型】
int PASCAL FAR WSAStartup(WORD wVersionRequired, LPWSADATA lpWSAData);
【使用说明】
每一个使用 winsock 的应用程序,都必须进行 WSAStart 函数调用,并且只有在调用成功之后才能使用其它的
winsock 网络操作函数。
WVersionRequired:<输入>表示欲使用的W insock 版本,这是一个 WORD 类型的整数,它的高位字节定义
的是次版本号,低位字节定义的是主版本号。
LpWSAData:<输出>是一个指向 WSADATA 资料的指针。这个资料我们一般不使用。
返回值:调用成功返回 0;否则,返回出错信息。
2. WSAClenaup():
【函数原型】
int PASCAL FAR WSACleanup(void);
【使用说明】
winsock 使用后,要调用W SACleanup 函数关闭网络设备,以便释放其占用的资源。
3.gethostname()
【函数原型】
int PASCAL FAR gethostname (char FAR * name, int namelen);
【使用说明】
该函数可以获取本地主机的主机名,其中:
name:<输出>用于指向所获取的主机名的缓冲区的指针。
Namelen:<输入>缓冲区的大小,以字节为单位。
返回值:若无错误,返回 0;否则,返回错误代吗。
4.gethostbyname()
【函数原型】
struct hostent FAR * PASCAL FAR gethostbyname(const char FAR * name);
【使用说明】
该函数可以从主机名数据库中得到对应的“主机”。
该函数唯一的参数 name 就是前面调用函数 gethostname()得到的主机名。若无错误,刚返回一个指向
hostent 结构的批针,它可以标识一个“主机”列表。
Hostent 结构定义如下:
Struct hostent