![]() |
DM&P DSock 编程指南 |
| DSock 首页: http://www.dmp.com.cn/tech/dsock | 2002/05/20 |
DSock是一个基于DOS系统实模式下的TCP/IP库,它通过RSIP使用。DSock提供简单的 C语言函数;利用DSock库函数,开发人员可以快速开发基于DOS系统的Internet程序, 从而节省大量开发时间。DSock库提供了丰富的例源程序代码,对于使用M6117D CPU的 DM&P产品用户,可以免费申请使用。
DSock库可以从我们的网站下载,这是一个Window自动解压缩文件,该文件解压缩后自动 创建一个DSock目录。DSock\Demo目录中有许多实例,所有实例已经顺利编译,并均打包 到DSock\Demo\EXE目录下。
Dsock库用Turbo C 2.0编译,因此推荐开发人员用Borland C++/Turbo C++编写开发程序。 如有必要,可以从网址 http://community.borland.com/article/images/21751/tcpp101.zip (2.63 MB)下载Turbo C++1.01。
本文档适用于运用DSock库,掌握TCP/IP协议,希望快速开发产品的开发人员。
DSock\Lib\PKTDRV目录下存有DSock软件包驱动程序,测试程序之前,务必安装这些驱 动程序。DSock库中的文件如下:
| 文件名称 | 描述 |
| LIB\DSOCK.H | DSock库头文件,C语言 |
| LIB\DSOCK.LIB | DSock链接库,DOS系统、大型记忆体模式 |
| LIB\DSOCK.CFG | 缺省网络配置文件 |
| LIB\LIB.HTM | DSock库参考文件 |
| LIB\PKTDRV\NE2000.COM | 8019AS软件包驱动 |
| LIB\PKTDRV\PKTDRV.BAT | 装载包驱动器的DOS批处理文件 |
DSock库函数浏览
系统函数
初始化和关闭DSock函数如下:
| 函数 | 描述 |
| DSock_Open() | 初始化DSock函数库 |
| DSock_Close() | 关闭DSock函数库 |
| DSock_DoBootp() | 从BOOTP/DHCP服务器获取网络设置 |
| DSock_LoadConfigFile() | 通过网络配置文件获取网络配置 |
设置/获取网络配置DSock函数如下:
| 函数 | 描述 |
| DSock_GetMacAddr() | 获取网卡的MAC地址 |
| DSock_GetHostIp() | 获取本机IP地址 |
| DSock_SetHostIp() | 设置本机IP地址 |
| DSock_GetNetmask() | 获取本机TCP/IP的网络掩码 |
| DSock_SetNetmask() | 设置本机TCP/IP的网络掩码 |
| DSock_GetGateway() | 获取网关IP地址 |
| DSock_AddGateway() | 设置网关IP地址 |
| DSock_GetDomainNameServer() | 获取DNS的IP地址 |
| DSock_AddDomainNameServer() | 设置DNS的IP地址 |
| DSock_Resolve() | 网络域名解析为对应IP地址 |
| 函数 | 描述 |
| inet_ntoa() | 将DWORD类型IP地址转为包含点分式IP地址 |
| inet_addr() | 将包含点分式IP地址的字符串转为DWORD类型IP地址 |
| ntohs() | 将一个WORD类型数据转为主机Byte类型数据排列 |
| ntohl() | 将一个DWORD类型数据转为主机Byte类型数据排列 |
| htons() | 将一个WORD类型数据转为网络Byte类型数据排列 |
| htonl() | 将一个DWORD类型数据转为网络Byte类型数据排列 |
| 函数 | 描述 |
| SocketCreate() | 创建一个套接字 |
| SocketDestory() | 释放一个套接字 |
| SocketClose() | 关闭一个套接字 |
| SocketAbort() | 中止一个套接字 |
| SocketBind() | 套接字IP地址和端口绑定 |
| SocketListen() | 套接字监听 |
| SocketAccept() | 套接字接受连接请求(非阻塞模式) |
| SocketConnect() | 与远端建立一个连接 |
| SocketIsConnected() | 检测套接字的连接状态 |
| SocketIsTcpPortUsed() | 检测TCP端口状态 |
| SocketIsUdpPortUsed() | 检测UDP端口状态 |
| SocketFindFreeTcpPort() | 搜寻一个空闲TCP端口 |
| SocketFindFreeUdpPort() | 搜寻一个空闲UDP端口 |
| SocketFlush() | 清空套接字缓冲区 |
| SocketFlushNext() | 套接字下一次读写操作到来时,清空套接字缓冲区 |
当套接字已经连接(UDP不需要连接),有关数据传送的DSock库函数如下:
| 函数 | 描述 |
| SocketSend() | 发送数据(阻塞模式) |
| SocketSend2() | 发送数据(非阻塞模式) |
| SocketRecv() | 接收数据(阻塞模式) |
| SocketRecv2() | 接收数据(非阻塞模式) |
| SocketPutChar() | 读入一个字符 |
| SocketGetChar() | 写入一个字符 |
| SocketGetString() | 读入一个字符串 |
| SocketPutString() | 写入一个字符串 |
| SocketDataReady() | 查询套接字已经接收数据的大小 |
#include "dsock.h"
#include <stdio.h>
int main()
{
/* Initialize DSock library */
if(DSock_Open()==FALSE)
{
printf("Unable to initialize socket library\n");
return 1;
}
/* Use BOOTP/DHCP to get setup */
if(DSock_DoBootp()==TRUE)
{
printf("Load network setup from BOOTP/DHCP\n");
}
else /* Load setup from config file */
{
printf("Unable to load setup from BOOTP/DHCP server\n");
DSock_LoadConfigFile("dsock.cfg");
printf("Load network setup from DSOCK.CFG\n");
}
/* You code here */
/* Close DSock library */
DSock_Close();
return 0;
}
|
char szBuf[32];
DWORD dwIp = DSock_Resolve("www.dmp.com.cn");
printf("IP of www.dmp.com.cn is %s\n",inet_ntoa(dwIp));
|
SOCKET s = SocketCreate(TCP_SOCKET); |
SOCKET s = SocketCreate(UDP_SOCKET); |
| Server | Client |
| SocketCreate() | SocketCreate() |
| SocketBind() | |
| SocketListen() | |
| SocketConnect() | |
| SocketAccept() | |
| SocketSend()/SocketRecv() | SocketRecv()/SocketSend() |
| SocketClose() | SocketClose() |
| SocketDestory() | SocketDestory() |
DSock库中的实例TALK_TCP通过源代码展示了这种服务器-客户端模式,实例源代码如下:
| 服务器 | 客户端 |
s = SocketCreate(TCP_SOCKET);
if(s==INVALID_SOCKET)
{
printf("SocketCreate() error\n");
DSock_Close();
return 1;
}
if(nArgCnt==1) /* Server mode */
TalkServer(s);
else /* Client mode */
TalkClient(s,pszArg[1]); |
|
if(SocketBind(s,0L,TALK_PORT)==FALSE)
{
printf("SocketBind() error\n");
return FALSE;
} |
|
if(SocketListen(s)==FALSE)
{
printf("SocketListen() error\n");
return FALSE;
}
printf("Talk server mode, listening...\n"); |
|
|
|
printf("Talk client mode, connecting to server...\n");
/* Connect to server */
if(SocketConnect(s,inet_addr(szServer),
TALK_PORT)==FALSE)
{
printf("SocketConnect() error\n");
return FALSE;
} |
/* Wait for client */
while(TRUE)
{
if(kbhit())
{
printf("Break by user\n");
break;
}
if(SocketAccept(s,&dwIp))
{
bConnected = TRUE;
inet_ntoa(szBuf,dwIp);
printf("Connected with %s\n",szBuf);
break;
}
}
|
|
/* Is connected with client ? */
if(bConnected)
{
printf("Start to talk...\n");
while(TRUE)
{
/* Check key press */
if(kbhit())
{
char c = getch();
SocketPutChar(s,c);
if(c==27)
{
printf("\nProgram terminated\n");
break;
}
}
/* Check message sent by client */
if(SocketDataReady(s))
{
char c;
SocketGetChar(s,&c);
printf("%c",c);
if(c==27)
{
printf("\nProgram terminated\n");
break;
}
}
}
} |
printf("Connected to %s:%d\n",szServer,TALK_PORT);
while(TRUE)
{
/* Check key press and send it out */
if(kbhit())
{
char c = getch();
SocketPutChar(s,c);
if(c==27)
{
printf("\nProgram terminated\n");
break;
}
}
/* Check key press sent by server */
if(SocketDataReady(s))
{
char c;
SocketGetChar(s,&c);
printf("%c",c);
if(c==27)
{
printf("\nProgram terminated\n");
break;
}
}
} |
SocketClose(s); SocketDestory(s); |
|
s = SocketCreate(UDP_SOCKET);
if(s==INVALID_SOCKET)
{
printf("SocketCreate() error\n");
DSock_Close();
return 1;
}
if(SocketBind(s,0xFFFFFFFFL,1234)==FALSE)
{
printf("SocketBind() error\n");
DSock_Close();
return 1;
}
printf("Start to talk, any press will be broadcast...\n");
while(TRUE)
{
/* User press keyboard ? */
if(kbhit())
{
char c = getch();
if(c == 27)
{
printf("\nProgram terminated\n");
break;
}
}
/* Is there any broadcast message ? */
if(SocketDataReady(s))
{
char c;
/* Save remote IP and port */
SocketRecvFrom(s, &dwAddr, &wPort,&c,1);
printf("From %s:%d, send '%c' back.\n", inet_ntoa(szBuf, dwAddr), wPort, c);
/* Send key press back to original port */
SocketSendTo(s, dwAddr, wPort, &c, 1);
if(c == 27)
{
printf("\nProgram terminated\n");
break;
}
}
}
SocketClose(s);
SocketDestory(s);
|
DSock库中实例TALK_UB的源代码示例了怎样用UDP广播,并展示可以接收被广播的消 息并,以及可以将键盘消息广播出去。实例源代码如下:
s = SocketCreate(UDP_SOCKET);
if(s==INVALID_SOCKET)
{
printf("SocketCreate() error\n");
DSock_Close();
return 1;
}
if(SocketBind(s,0xFFFFFFFFL,1234)==FALSE)
{
printf("SocketBind() error\n");
DSock_Close();
return 1;
}
printf("Start to talk, any press will be broadcast...\n");
while(TRUE)
{
/* User press keyboard ? */
if(kbhit())
{
char c = getch();
SocketPutChar(s,c);
if(c==27)
{
printf("\nProgram terminated\n");
break;
}
}
/* Is there any broadcast message ? */
if(SocketDataReady(s))
{
char c;
SocketGetChar(s,&c);
printf("%c",c);
if(c==27)
{
printf("\nProgram terminated\n");
break;
}
}
}
SocketClose(s);
SocketDestory(s);
|
#define MAX_SOCKET 5
SOCKET s[MAX_SOCKET];
for(i=0;i<MAX_SOCKET;i++)
{
s[i] = SocketCreate(TCP_SOCKET);
if(s==INVALID_SOCKET)
return;
if(SocketBind(s[i],0L,nPort)==FALSE)
return;
if(SocketListen(s[i])==FALSE)
return;
}
while(TRUE)
{
for(i=0;i<MAX_SOCKET;i++)
if(SocketAccept(s[i],&dwIp))
{
/* Do Job Here */
break;
}
}
|
| 文件名称 | 描述 |
| LIB.HTM | DSock库参考文件 |
| LIB\DSOCK.H | DSock库头文件,C语言 |
| LIB\DSOCK.LIB | DSock库,DOS系统、大型记忆体模式 |
| LIB\DSOCK.CFG | 缺省网络配置文件 |
| LIB\PKTDRV\NE2000.COM | 8019AS包驱动文件 |
| LIB\PKTDRV\PKTDRV.BAT | 装载包驱动的DOS 批处理文件 |
| Example Name | 描述 |
| DEMO\BOOTP | 利用BOOTP/DHCP从DHCP服务器获取网络配置 |
| DEMO\DNS | 根据网络域名解析获得对应的IP地址 |
| DEMO\FTPD | FTP服务器实例,缺省用户名是“dmp”,缺省密码是“dmp” |
| DEMO\HTTPD | Web服务器实例 |
| DEMO\SMTP | 发送e-mail的一个程序 |
| DEMO\SMTPD | SMTP服务器实例 |
| DEMO\TELNETD | 简单的TELNET服务器实例,缺省用户名是“dmp”,缺省密码是“dmp” |
| DEMO\TALK_S | 多TCP连接的谈话服务器实例 |
| DEMO\TALK_TCP | 运用TCP完成的谈话实例 |
| DEMO\talk_tcp_win | 用WinSock编写的Windows版本谈话(TCP) |
| DEMO\TALK_UB | 运用广播完成的谈话实例 |
| DEMO\talk_ub_win | 用WinSock编写的Windows版本谈话(UB) |
| DEMO\TALK_UDP | 运用UDP完成的谈话实例 |
| DEMO\talk_udp_win | 用WinSock编写的Windows版本谈话(UDP) |
| DEMO\SOCK_AP | 支持FTP/HTTP/SMTP/TELNET的一个启动工程 |
典型DSOCK.CFG文件配置信息示例如下:
ip=192.168.0.234 netmask=255.255.255.0 gateway=192.168.0.1 nameserver=192.168.0.1 |
如果没有DNS服务器,nameserver标记符这样设置:“nameserver=”。如果没有网关,gateway
标记符的设置方法和nameserver标记符相同。
包驱动器
DSock库为386 SX CPU M6117D设计,Realtek 8019AS芯片用于通信板中。缺省IRQ的设置为
5,缺省I/O地址的设置为320H,所以必须在批处理文件autoexec.bat中加入以下内容:
ne2000 0x62 5 0x320 |
| 文件名称 | 描述 |
| X-DOS | 在DM&P 单板机上可以免费使用X-DOS |
| AUTOEXEC.BAT | 装载包驱动器,引导你的程序 |
| NE2000.COM | 8019AS包驱动器文件 |
| DSOCK.CFG | DSock库网络配置文件 |
| Your App | 运用DSock库编写的程序 |
如果设备不能用X-DOS引导,可以拷贝这些文件到存储设备(Flash Disk/DOC/DOM),否则需
要首先安装X-DOS。利用"MakeROM"工具,
可以为Mity-Mite模块制作一个ROM映像,从而节省
DOC/DOM;一旦存储设备具有Mity-Mite模块,通电后就具有了Internet功能。
技术支持
如果你在使用DSock中出现任何问题,请联系我们,邮件地址:tech@dmp.com.cn please.
| Jan Yin Chan Electronics Co., LTD. 保留所有权利. | Email us: tech@dmp.com.cn |