?? dosnetworkprogrammimg.txt
字號:
DOS下的網絡編程
第一章 安裝網卡的DOS驅動程序
網卡的DOS驅動程序一般由硬件的生產廠商提供,微軟的DOS網絡安裝包<Microsoft Network Client Version3.zip>在本目錄下,里面也包含了很多早期的網卡驅動。在本目錄有一個WAFER-C400小主板上網卡的驅動程序<網卡RTL8139驅動(DOS).rar>,非常通用,我們大部分計算機都可以使用它。
<Microsoft Network Client Version3.zip>解壓后,把里面的文件都拷貝到DOS系統盤c:\netsetup目錄下,把<網卡RTL8139驅動(DOS).rar>解壓后拷貝到c:\netsetup\driver目錄下。
運行c:\netsetup\setup.exe,當然,是在MS-DOS系統中運行,按照步驟操作。
在下面的列表中選擇自己的網卡,因為這些都是早期的型號,我們使用的網卡在這里一般是不會找到的,所以選擇“Network adapter not shown on list below ...”。
然后輸入網卡驅動所在的目錄“c:\netsetup\driver”,程序自己就會找到目錄下的驅動,回車進行下一步,隨意輸入個用戶名,例如“yangzhpeng”。到這一步要對自己的網絡細致地設置了,不能貿然進行下一步。
其實我們要設置的項也不多。修改用戶名,機器名,工作組和域不用管。
修改網絡配置,把NWLink協議去掉,添加上TCP/IP協議。并且修改TCP/IP協議的設置。
把Disable Automatic Configuration設置成1(很重要),修改IP地址和掩碼。
現在就可以放心地安裝了。安裝之后重啟計算機。
第二章 檢查DOS下的網絡配置
在上一章安裝完成之后,有三個文件對我們很重要。第一個是c:\config.sys文件,有句話“device=C:\NET\ifshlp.sys”,是安裝程序給寫上的。
第二個文件是c:\autoexec.bat,安裝程序在文件的最后添加了這些話:
C:\NET\netbind.com
C:\NET\umb.com
C:\NET\tcptsr.exe
C:\NET\tinyrfc.exe
C:\NET\nmtsr.exe
C:\NET\emsbfr.exe
C:\NET\net start
我們把修改成:
C:\NET\net initialize
C:\NET\netbind.com
C:\NET\umb.com
C:\NET\tcptsr.exe
C:\NET\tinyrfc.exe
C:\NET\nmtsr.exe
C:\NET\emsbfr.exe
C:\NET\sockets.exe
網絡驅動安裝完畢,下一步要編寫程序。
第三章 編程環境
需要4步:(1)假定使用Borland C++ 4.5,假定安裝在c:\bc45。
本目錄下面有一個Microsoft TCPIP Sockets Development Kit Version 1.0的壓縮包<MSTCPSDK.rar>。解壓后,把MSTCPSDK\INCLUDE\中的全部文件拷貝到c:\bc45\INCLUDE\中。
(2)如果編寫的是C++程序,還要修改\INCLUDE\SOCKDEFS.H文件,把全部內容用extern "C" {……}圈起來。
(3)程序中應該包括下面的頭文件:
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <netinet/in.h>
(4)還應該把MSTCPSDK\LIB\DOS_SOCK.LIB文件加入到程序工程中。
如果覺得這樣做比較麻煩,那就使用我整理的文件,在本目錄中的dos_sock.rar。只有兩個文件dos_sock.h和dos_sock.lib,把這兩個文件加入工程中,然后#include “dos_sock.h”就可以了。
第四章 SOCKET概述
1 TCP/IP網絡模型
TCP/IP是Transmission Control Protocol / Internet Protocol(傳輸控制協議/網際協議)的縮寫。它最初是在20世紀70年代由美國國防部出資為ARPA(美國高級研究項目局)開發的。經過多年的演變,以TCP/IP協議為基礎構建的ARPA網逐漸成了今天的Internet。
TCP/IP協議的核心協議包括TCP,UDP和IP協議, 運行于傳輸層和Internet層上,其中TCP和UDP協議是以IP協議為基礎而封裝的,這兩種協議提供了不同方式的數據通信服務。
如果說IP協議是道路,那么下一層網絡訪問層的各種協議就相當于不同的鋪路材料,而上一層的TCP和UCP協議就相當于路上跑的不同類型的車輛;再上層應用層的各種協議就車上豐富多彩的貨物,它們都是以TCP和UDP協議為載體完成的。比如,HTTP協議適使用TCP協議傳輸網頁,POP3協議使用TCP協議傳輸郵件,而DNS協議使用UDP協議來傳輸域名和IP地址的翻譯信息。
2 IP地址和端口
在使用TCP和UDP協議通信時,必須同時指定IP地址和端口號才能完整地標識一個通信地址,在編程中通常將這兩個參數一起定義在一個sockaddr_in結構中來使用。
struct sockaddr_in
{
short sin_family; //地址格式
unsigned short sin_port; //端口號(使用網絡字節順序)
struct in_addr sin_addr; //IP地址(使用網絡字節順序)
char sin_zero[8]; //空字節
};
結構中的sin_family字段用來指定地址格式,在不同的操作系統下,取值可以指定為AF_UNSPEC,AF_UNIX或AF_OSI等不同的值,但是在這里我們只能使用AF_INET。
sin_addr字段是個in_addr結構,這個結構實際上就是4個字節。
3 網絡字節順序
不同的處理器對字節順序的處理方式不同,有的是高位在前,有的是低位在前。TCP/IP協議統一規定使用高位在前的方式傳輸數據,很遺憾,這與Intel80x86系列處理器使用的方式不同,所以在80x86平臺下的socket編程中,當需要在協議中使用參數時,必須首先將它們轉換為Internet順序。
在填寫sockaddr_in結構的sin_port字段和sin_addr字段時,必須首先進行轉換。下面就是一些字節轉換函數:
16位:
unsigned shorthtons(unsigned short); //主機順序-->網絡順序
unsigned shortntohs(unsigned short); //網絡順序-->主機順序
32位:
unsigned long htonl(unsigned long); //主機順序-->網絡順序
unsigned long ntohl(unsigned long); //網絡順序-->主機順序
4 IP地址轉換函數
unsigned long inet_addr(char far *);
將“aa.bb.cc.dd”類型的十進制字符串轉換成32位的IP地址。如果失敗,返回INADDR_NONE。
char far * inet_ntoa(struct in_addr);
將網絡字節順序的32位IP地址轉換成字符串。返回一個指針,指向轉換后的IP地址字符串,這個字符串位于socket接口的內部緩沖區,所以,在調用inet_ntoa后必須馬上把字符串拷貝到自己定義的緩沖區中。
5 套接字
兩個主機之間進行網絡傳輸,首先必須建立一個用來通信的對象,這個對象就稱為套接字(socket),套接字的定義是“通信的一端”,在通信的另一端必定有另一個套接字與之相對應,以便互相傳遞數據。僅從編程的角度來看,套接字就是一個整數標識符而已,但使用socket這個稱呼好像更貼切。
套接字的種類有很多種,最主要的是流套接字(stream socket)和數據報套接字(datagram socket)。由于流套接字使用傳輸層的TCP協議進行通信,所以它具有TCP協議所擁有的各種特征,比如:它是面向連接的、穩定的,以及數據包是按順序發送的;而數據包套接字使用UDP協議進行通信,所以數據包可能丟失,可能重復,以及可能不按順序到達等。一般將這兩種套接字更直觀地稱為TCP套接字和UDP套接字。
還有一種原始套接字(raw socket),可以直接在Internet層上處理IP數據包首部,所以可以用它是個各種特殊的功能,如偽造發送者地址等。
由于我們在工作實際應用中使用的是TCP協議,所以在本篇也只討論TCP套接字。對應于dos_sock.lib文件,我們把MS-DOS編程中使用的socket叫做dos_sock。
6 套接字的創建和關閉
創建套接字使用socket函數:
int socket(int af, int type, int protocol);
函數使用的第一個參數af用來指定套接字使用的地址格式,和sockaddr_in結構的sin_family字段的定義是一樣的,唯一可以使用的值是AF_INET。
第二個參數type用來指定套接字的類型。正如前面介紹的,套接字有流套接字(SOCK_STREAM)、數據報套接字(SOCK_DGRAM)和原始套接字(SOCK_RAW)等。
protocol參數配合type參數的使用,用來指定使用的協議類型,當type參數指定為SOCK_STREAM或者SOCK_DGRAM的時候,系統已經明確使用TCP和UDP協議來工作,所以,這時這個參數并沒有什么意義,可以指定為0。但是當type參數指定為SOCK_RAW類型的時候,使用protocol參數可以更詳細地指定原始套接字的工作方式。
當套接字被成功創建的時候,函數將返回一個套接字句柄,否則函數將返回INVALID_SOCKET(定義為-1或者~0)。
當不需要使用套接字的時候,使用closesocket函數將它關閉:
int closesocket(int s); s就是創建套接字時返回的套接字句柄。
7 套接字的工作模式
socket的使用分為兩種模式:阻塞模式和非阻塞模式。阻塞模式也稱為同步模式,socket函數會等待操作完成之后才返回。比如,使用recv函數接收數據時,如果函數被調用時沒有數據可收,那么函數不會返回,直到收到一些數據為止。再比如使用send函數發送n字節的數據時,在全部n字節發送完之前,函數不會返回,所以這時,程序處在等待狀態。
非阻塞模式又稱為異步模式,同樣是前面的情況,recv和send函數執行后會立即返回,等到數據數據到達或者鏈路空閑可以繼續發送數據時,socket接口會通過某種形式通知應用程序。
Windows中使用的Socket(WinSock2)默認是阻塞模式,不知道dos_sock的默認狀態是阻塞還是非阻塞,沒有找到相關資料。設置阻塞模式的函數是:
int ioctl(int s, int cmd, char far *pArgument); s是套接字句柄,cmd是要執行的操作,pArgument是cmd要設置的參數。函數執行成功返回0,出錯返回-1。
設置dos_sock為非阻塞模式:
DWORD value = 1; //非0非阻塞
int result = ioctl(s, FIONBIO, (char far *)(&value));
設置dos_sock為阻塞模式:
DWORD value = 0; //是0是阻塞
int result = ioctl(s, FIONBIO, (char far *)(&value));
8 使用setsockopt設置套接字的屬性
函數的原形是:
int setsockopt(
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -