char *ip; //定义IP地址变量 PHOSTENT hostinfo;
//调用MAKEWORD()获得Winsock版本的正确值,用于加载Winsock库
if ( WSAStartup( MAKEWORD(2,0), &wsaData ) == 0 ) {
//现在是加载Winsock库,如果WSAStartup()函数返回值为0,说明加载成功,程序可以继续
if( gethostname ( name, sizeof(name)) == 0) {
//如果成功地将本地主机名存放入由name参数指定的缓冲区中 if((hostinfo = gethostbyname(name)) != NULL) {
//这是获取主机名,如果获得主机名成功的话,将返回一个指针,指向hostinfo,hostinfo
//为PHOSTENT型的变量,下面即将用到这个结构体 ip = inet_ntoa (*(struct in_addr *)*hostinfo->h_addr_list);
//调用inet_ntoa()函数,将hostinfo结构变量中的h_addr_list转化为标准的点分表示的IP
//地址(如192.168.0.1) printf(\输出IP地址 } }
WSACleanup( ); //卸载Winsock库,并释放所有资源 } }
int main(void) {
CheckIP(); return 0; }
对上面的解释: 什么是Winsock
Winsock是Windows下的网络编程接口,它是由Unix下的BSD Socket发展而来,是一个与网络协议无关的编程接口。 构建编程环境
Winsock在常见的Windows平台上有两个主要的版本,即Winsock1和Winsock2。编写与Winsock1兼容的程序你需要引用头文 件WINSOCK.H,如果编写使用Winsock2的程序,则需要引用WINSOCK2.H。此外还有一个MSWSOCK.H头文件,它是专门用来支持 在Windows平台上高性能网络程序扩展功能的。使用WINSOCK.H头文件时,同时需要库文件WSOCK32.LIB,使用WINSOCK2.H 时,则需要WS2_32.LIB,如果使用MSWSOCK.H中的扩展API,则需要MSWSOCK.LIB。正确引用了头文件,并链接了对应的库文件, 你就构建起编写WINSOCK网络程序的环境了。 初始化Winsock
每个Winsock程序必须使用WSAStartup载入合适的Winsock动态链接库,如果载入失败,WSAStartup将返回SOCKET_ERROR,这个错误就是WSANOTINITIALISED,WSAStartup的定义如下:
13
int WSAStartup(
WORD wVersionRequested, LPWSADATA lpWSAData );
wVersionRequested指定了你想载入的Winsock版本,其高字节指定了次版本号,而低字节指定了主版本号。你可以使用宏 MAKEWORD(x, y)来指定版本号,这里x代表主版本,而y代表次版本。lpWSAData是一个指向WSAData结构的指针,WSAStartup会向该结构中填充其 载入的Winsock动态链 库的信息。
lpWSAData是一个指向WSAData结构的指针,WSAStartup会向该结构中填充其载入的Winsock动态链 库的信息。
lpWSAData是一个指向WSAData结构的指针,WSAStartup会向该结构中填充其载入的Winsock动态链 库的信息。
typedef struct WSAData {
WORD wVersion; WORD wHighVersion;
char szDescription[WSADESCRIPTION_LEN + 1]; char szSystemStatus[WSASYS_STATUS_LEN + 1]; unsigned short iMaxSockets; unsigned short iMaxUdpDg; char FAR * lpVendorInfo; } WSADATA, * LPWSADATA;
wVersion为你将使用的Winsock版本号,wHighVersion为载入的Winsock动态库支持的最高版本,注意,它们的高字节代表次版本,低字节代表主版本。
szDescription与szSystemStatus由特定版本的Winsock设置,实际上没有太大用处。 iMaxSockets表示最大数量的并发Sockets,其值依赖于可使用的硬件资源。
iMaxUdpDg表示数据报的最大长度;然而,获取数据报的最大长度,你需要使用WSAEnumProtocols对协议进行查询。
最大数量的并发Sockets并不是什么神奇的数字,它是由可用的物理资源来决定的.
lpVendorInfo是为Winsock实现而保留的制造商信息,这个在Windows平台上并没有什么用处.
自Windows 95以后的操作系统都支持Winsock 2.2的版本.即使是这样,你也不能认为这些Windows平台支持最新的Winsock版本,为了让你的程序能够运行于大多数平台,最好使用Winsock1.1规范.
当你使用完Winsock接口后,要调用下面的函数对其占用的资源进行释放:
14
int WSACleanup(void);
如果调用该函数失败也没有什么问题,因为操作系统为自动将其释放,对应于每一个WSAStartup调用都应该有一个WSACleanup调用.
错误处理
Winsock函数调用失败大多会返回 SOCKET_ERROR(实际上就是-1),你可以调用
WSAGetLastError得到错误的详细信息:
int WSAGetLastError (void);
对该函数的调用将返回一个错误码,其码值在WINSOCK.H或WINSOCK2.H(根据其版本)中已经定义,这些预定义值都以WSAE开头.同时你还可以使用WSASetLastError来自定义错误码值.
17 大型文件传输要考虑哪些方面?文件续传功能应如何考虑?
1.功能性问题:不同网络情况下的传输问题、大文件传输、传输取消机制、请求保存时间、各种文件的传输
2。安全性问题:病毒传输,隐私泄露等
文件续传功能应该考虑,文件断点,文件头和尾有没问题
18 简述NAT的过程
1).静态地址转换的实现 第一步,设置外部端口。 第二步,设置内部端口。
第三步,在内部本地与外部合法地址之间建立静态地址转换。 2).动态地址转换的实现 第一步,设置外部端口。 第二步,设置内部端口。 第三步,定义合法IP地址池。
第四步,定义内部网络中允许访问Internet的访问列表。 第五步,实现网络地址转换。 3).端口复用动态地址转换(PAT) 第一步,设置外部端口。 第二步,设置内部端口。 第三步,定义合法IP地址池。 第四步,定义内部访问列。 第五步,设置复用动态地址转换。
15
19 什么是网络字节顺序与主机字节顺序?如果要在网络上传输一个文件的长度(unsigned long),应如何处理?
主机字节,通俗点说你用的电脑内存里存放整数,浮点数的方式就是主机字节 因为大多用的都是intel的 x86体系
所以这里主机字节,就是描述整数或者浮点数的,字节在内存中的存放,低字节在前,高字节在后的排列
网络字节么,就是在网络上描述整数或者浮点数的字节s哪一个字节被先发出去,通常是高字节在前,低字节在后
20 已知建立连接的套接字s,如何得到通信双方的地址信息?
#include
#pragma comment(lib,\
int recvline(SOCKET s,char* c) {
int i=0;
while(::recv(s,c+i,1,0)>0) {
if(c=='\\n') break; i++; }
if( c=='\\n') {
c[i-1]=0; return i-1; }
return false; }
int main() {
/*初始化socket版本*/
WSADATA wsa;
WSAStartup(MAKEWORD(2,2),&wsa); /*远程主机信息*/ struct sockaddr_in sin;
sin.sin_family = AF_INET;
16

