Download presentation
Presentation is loading. Please wait.
1
《信息通信网络概论》课程实验 东南大学自动化学院
2
网络编程实验 Windows Socket 编程基础知识 实验一 实验二、三 实验四 实验五、六
3
Windows Socket 网络编程 Windows Socket 简介 套接字编程基础 Windows Socket 编程原理
4
一、Windows Socket的由来 加利福尼亚大学伯克利分校为UNIX系统开发出了伯克利套接字(BSD socket),在此基础上扩展形成了windows套接字。 Windows Socket 规范是一套开放的、支持多协议的Windows 下的网络编程接口,它规范了Internet协议族(IPS,一般为TCP/IP)的API使用. 针对多样的网络协议,Windows Socket 统一了操作,简化了编程,使两个进程之间实现连接、通信。
5
二、windows socket 的版本 Windows Socket 规范主要有两种版本即1.1和2.0版。 主要区别:1.1版本只支持TCP/IP协议,2.0版本可以支持多协议 三、编程时的加载事项 •需要包含头文件Winsock2.h,需要使用库ws2_32.lib,包含办法可以用语句来告诉编译时调用该库 #pragma comment(lib,”ws2_32.lib”); 如果使用Visual C++ 6.0,可以通过“工程” > “设置”>“工程设置”>“链接”>“对象/库模块”中加入“ws2_32.lib”
6
• WinSock是TCP/IP编程最低级的Windows API,其代码的一部分位于Winsock32
• WinSock是TCP/IP编程最低级的Windows API,其代码的一部分位于Winsock32.dll中,另一部分位于Windows核心,使用Windows API可以编写Internet 服务器和客户端程序。应用程序调用Windows Socket 的API实现相互之间的通信(应用程序与Windows Socket关系图)
7
网络编辑界面,如Windows Sockets
应用程序1 应用程序2 网络编辑界面,如Windows Sockets 网络通信协议服务,如TCP/IP 操作系统,如Windows 物理通信介质 操作系统为保证其安全性可靠性不允许用户直接使用 TCP/IP协议被集成到操作系统的内核中,引入了新型的“I/O”操作 进行网络操作的两个进程在不同的机器上,如何连接? 网络协议具有多样性,如何进行统一的操作 独立于具体协议的网络编程接口 在ISO模型中,主要位于会话层和传输层之间 应用程序与Windows Socket 关系图 返回
8
套接字有三种类型 数据报套接字(SOCK_DGRAM)——一种无连接的服务,数据通过相互独立的报文进行传输,是无序的,并且不保证可靠、无差错 (时序图) 流式套接字(SOCK_STREAM)——一种可靠的面向连接的服务,实现了无差错无重复的顺序数据传输 (时序图) 原始套接字(SOCK_RAW)——允许对底层协议如IP或ICMP(因特网控制消息协议)直接访问,主要用于新的网络协议实现的测试等 返回
9
网络连接函数 socket 创建套接字 bind 绑定本机接口 connect 建立连接 listen 监听端口 accept 接受连接
recv,recvfrom 数据接收 send,sendto 数据发送 close,shutdown 关闭套接字
10
基本概念 IP地址:Internet中的主机要与别的机器通信必须具有一个IP地址,IP地址是Internet中主机的标识。
表示形式:常用点分形式,如 ,最后都会转换为一个32位的整数。 IP地址转换函数 inet_addr() 点分十进制数表示的IP地址转换为网络字节序的IP地址 inet_ntoa() 网络字节序的IP地址转换为点分十进制数表示的IP地址
11
端口号 为了区分一台主机接收到的数据包应该递交给哪个进程来进行处理,使用端口号 TCP端口号与UDP端口号独立
端口号一般由IANA (Internet Assigned Numbers Authority) 管理 众所周知端口:1~1023,1~255之间为大部分众所周知端口,256~1023端口通常由UNIX占用 注册端口:1024~49151 动态或私有端口:49151~65535
12
比喻: 如果把IP数据包的投递过程看成是给远方的一位朋友寄一封信,那么
端口号就是这位朋友的名字(依靠这个信息最终把这封信交付给这位收信者)
13
字节序 大尾端(Big-Endian):字节的高位在内存中放在存储单元的起始位置 小尾端(Little-Endian):与大尾端相反
不同的机器HBO是不一样的,这与CPU的设计有关 Motorola 68K系列,HBO与NBO是一致的 Intel X86系列,HBO与NBO不一致
14
网络字节序(NBO,Network Byte Order)
使用统一的字节顺序,避免兼容性问题 主机字节序(HBO,Host Byte Order) 不同的机器HBO是不一样的,这与CPU的设计有关 Motorola 68K系列,HBO与NBO是一致的 Intel X86系列,HBO与NBO不一致 字节排序函数 htonl 4字节主机字节序转换为网络字节序 ntohl 4字节网络字节序转换为主机字节序 htons 2字节主机字节序转换为网络字节序 ntohs 2字节网络字节序转换为主机字节序
15
阻塞通信与非阻塞通信 阻塞方式:套接字进行I/O操作时,函数要等待到相关的操作完成以后才能返回,对提高处理机的利用率不利,但编程简单。 非阻塞方式:套接字进行I/O操作时,无论操作成功与否,调用都会立即返回。 阻塞方式编程简单,一个套接口的默认操作模式为阻塞,可以调用函数ioctlsocket()进行设置。
16
面向连接的C/S网络通信程序工作流程图(TCP)
套接字的工作过程如下:服务器首先启动,通过调用socket()建立一个套接字,然后调用bind()将该套接口和本地网络地址联系在一起,再调用listen()使套接口做好侦听的准备,并规定它的请求队列的长度,之后调用accept()来接收连接。客户建立套接口后即可调用connect()和服务器建立连接。连接一旦建立,客户机和服务器之间就可以通过调用read()和write()来发送和接收数据。最后,待数据传送结束后,双方调用close()关闭套接口。 返回
17
无连接的C/S网络通信程序工作流程图(UDP)
这个bind可以是 隐式的。 无连接服务器一般都是面向事务处理的,一个请求、一个应答就完成了客户程序与服务程序之间的相互作用。 首先,客户机和服务器都要创建一个数据报套接字。连接服务器调用bind()函数给套接字分配一个公认的端口。在开发应用程序时,这个公认的端口通常是指定的,这样客户机和服务器就使用同样的端口来表示服务器套接字。一旦服务器将公认的端口分配给了套接字,客户机就能够使用sendto()函数向服务器发送数据、信息。同样客户机和服务器都能够使用sendto()和recvfrom()来传递数据报直到完成传递。然后调用closesocket()来关闭套接字。 返回
18
注意事项: 无连接的数据报传输过程中,作为服务器的一方必须先启动 通信的一方可以不用bind()绑定地址和端口,由系统分配
不绑定IP地址和端口号的一方必须首先向绑定地址的一方发送数据 无连接客户端一般不调用connect(),在数据发送前客户与服务器各自通过socket()和bind()建立了半相关,发送数据时除指定本地套接口的地址外,还需要指定接收方套接口地址,从而在数据收发过程中动态建立全连接 返回
19
为了支持Windows的消息驱动机制,WinSock和BSD套接口相比有以下一些扩充:
异步选择机制 异步选择函数WSAAsyncSelect()允许应用程序提名一个或多个感兴趣的网络事件,如FD_READ、FD_WRITE、FD_CONNECT、FD_ACCEPT等代表的网络事件 异步请求函数 异步请求函数允许应用程序用异步方式获得请求的信息,如WSAAsyncGetXByY()类函数,这些函数是对BSD标准函数的扩充。函数WSACancelAsyncRequest()允许用户终止一个正在执行的异步请求 阻塞处理方法 WinSock提供了“钩子函数”负责处理Windows消息,使Windows的消息循环能够继续。WinSock提供了两个函数(WSASetBlockingHool()和WSAUnhookBlockingHook())让应用程序设置或取消自己的“钩子函数”。函数WSAIsBlocking()可以检测是否阻塞,函数WSACancelBlockingCall()可以取消一个阻塞的调用 错误处理 WinSock提供了两个函数WSAGetLastError()和WSASetLastError()来获取和设置最近的错误号 启动和终止 异步相比与同步提高了性能更具优势,不需要 在接收完一个网络事件完后等待其处理完成, 而可以继续接收其他网络事件。CAsyncSocket
20
调用终止函数WSACleanup()来终止Windows Sockets DLL。
Winsock 的启动和终止 应用程序在使用Windows Sockets Dll之前必须先调用启动函数WSAStartup()。该函数的功能有两个:一是由应用程序指定所要求的Windows Sockets Dll 版本;二是获得系统Windows Sockets Dll的一些细节。 调用终止函数WSACleanup()来终止Windows Sockets DLL。 返回
21
Socket 编程过程 (主要讲解使用Socket的过程)
使用WSAStartup()函数检查系统协议栈安装情况 使用Socket()函数创建套接口 socket_handle=socket(protocol_family.Socket_type,protocol); 配置Socket 配置一个socket需要五种信息: 本地和远地机的IP地址 本地和远地进程的协议端口 连接所使用的协议 使用Socket发送或接收数据 使用send或sendto方法发送数据,recv或recvfrom方法接收数据。 使用WSACleanup()函数关闭与Windows Sockets DLL 的连接 返回
22
实验一 实验内容:使用Socket 函数编写一个小程序实现查询主机地址即输入IP地址能够给出该IP地址对应的域名;给出域名可以给出IP地址。
实验要求:理解掌握WSAStartup()、WSACleanup() 函数的使用;知道WSADATA、HOSTENT结构成员表示意义和inet_ntoa()、inet_addr()函数的使用。 主要步骤: 1、网络程序初始化,调用其它WinSock函数之前先使用WSAStartup()函数初始化 2、通过WinSock发送和接收数据 3、程序结束必须关闭Socket,使用WSACleanup()释放所分配的内部 缓冲区和其他资源。 记录主机信息,包括主机 名、别名、地址类型、 地址列表等。 IP地址的点分十进制字符串(如" ") 与IN_ADDR 结构体之间的相互转化 struct WSAData { WORD wVersion; WORD wHighVersion; char szDescription[WSADESCRIPTION_LEN+1]; char szSystemStatus[WSASYSSTATUS_LEN+1]; unsigned short iMaxSockets; unsigned short iMaxUdpDg; char FAR * lpVendorInfo; }; The WSADATA structure is used to store Windows Sockets initialization information returned by a call to the AfxSocketInit global function. Members wVersion The version of the Windows Sockets specification that the Windows Sockets DLL expects the caller to use. wHighVersion The highest version of the Windows Sockets specification that this DLL can support (also encoded as above). Normally this is the same as wVersion. szDescription A null-terminated ASCII string into which the Windows Sockets DLL copies a description of the Windows Sockets implementation, including vendor identification. The text (up to 256 characters in length) can contain any characters, but vendors are cautioned against including control and formatting characters: the most likely use that an application will put this to is to display it (possibly truncated) in a status message. szSystemStatus A null-terminated ASCII string into which the Windows Sockets DLL copies relevant status or configuration information. The Windows Sockets DLL should use this field only if the information might be useful to the user or support staff; it should not be considered as an extension of the szDescription field. struct hostent { char FAR * h_name; char FAR * FAR * h_aliases; short h_addrtype; short h_length; char FAR * FAR * h_addr_list; }; Members h_name Official name of the host (PC). If using the DNS or similar resolution system, it is the Fully Qualified Domain Name (FQDN) that caused the server to return a reply. If using a local hosts file, it is the first entry after the IP address. h_aliases Null-terminated array of alternate names. h_addrtype Type of address being returned. h_length Length of each address, in bytes. h_addr_list Null-terminated list of addresses for the host. Addresses are returned in network byte order. The macro h_addr is defined to be h_addr_list[0] for compatibility with older software. unsigned long inet_addr( const char FAR *cp ); Parameters cp [in] Null-terminated character string representing a number expressed in the Internet standard ".'' (dotted) notation. Return Values If no error occurs, inet_addr returns an unsigned long value containing a suitable binary representation of the Internet address given. If the string in the cp parameter does not contain a legitimate Internet address, for example if a portion of an "a.b.c.d" address exceeds 255, then inet_addr returns the value INADDR_NONE. char FAR * inet_ntoa( struct in_addr in ); Parameters in [in] Structure that represents an Internet host address. If no error occurs, inet_ntoa returns a character pointer to a static buffer containing the text address in standard ".'' notation. Otherwise, it returns NULL.
23
int WSAStartup(WORD wVersionRequested,LPWSADATA lpWSAData);
函数说明: ① wVersionRequested是应用程序对Windows Sockets DLL版本要求。高字节代表次版本号,低字节代表主版本号。如定义wVersionRequested=0x0002,则表示应用程序对DLL的最低要求为2.0版本 ②lpWSAData用于返回Windows Sockets DLL的一些技术细节,是指向WSAData结构的一个指针。其中WSAData的成员变量wHighVersion指明DLL支持的最高版本,成员变量wVersion代表wHighVersion与wVersionRequested的最小值,也就是DLL希望用户使用的版本号 ③ 函数调用成功,返回值0;若失败,则返回错误码,可用WSAGetLastError()查看 下面举例说明函数的使用
24
实验一界面样例 Windows Sockets DLL的初始化过程 WORD wVersionRequested;
WSADATA wsaData; Int err; wVersionRequested=0x0002; Err=WSAStartup(wVersionRequested,&wsaData); If(err!=0) { /*通知用户找不到可用的Winsock DLL*/ Return; } If(wsaData.wVersion!=0x0002) /*通知用户找不到可用的Winsock DLL,因为当前Winsock版本低于2.0*/ WSACleanup(); /*协商成功,启动了DLL*/ 实验一界面样例
25
返回
26
实验二、三 实验内容:编写一个连接FTP程序,实现检索FTP文件服务器、上传文件、下载文件。 理解FTP协议是非对称的协议。
实验要求:理解掌握CInternetSession()、GetFtpConnection()、 CFtpFileFind()、GetFile()、PutFile()、 FindNextFile()函数的使用 CInternetSession( LPCTSTR pstrAgent = NULL, DWORD dwContext = 1, DWORD dwAccessType = INTERNET_OPEN_TYPE_PRECONFIG, LPCTSTR pstrProxyName = NULL, LPCTSTR pstrProxyBypass = NULL, DWORD dwFlags = 0 ); Parameters pstrAgent A pointer to a string that identifies the name of the application or entity calling the Internet functions (for example, "Microsoft Internet Browser"). If pstrAgent is NULL (the default), the framework calls the global function AfxGetAppName, which returns a null-terminated string containing an application’s name. Some protocols use this string to identify your application to the server. dwContext The context identifier for the operation. dwContext identifies the operation’s status information returned by CInternetSession::OnStatusCallback. The default is set to 1; however, you can explicitly assign a specific context ID for the operation. The object and any work it does will be associated with that context ID. If dwFlags includes INTERNET_FLAG_ASYNC, then objects created by this object have asynchronous behavior as long as a status callback routine is registered. In order for a function to be completed synchronously, dwContext has to be set to zero for that call. dwAccessType The type of access required. The following are valid values, exactly one of which may be supplied: INTERNET_OPEN_TYPE_PRECONFIG Preconfigured (in the registry). This access type is set as the default. INTERNET_OPEN_TYPE_DIRECT Direct to Internet. INTERNET_OPEN_TYPE_PROXY Through CERN proxy. pstrProxyName The name of the preferred CERN proxy if dwAccessType is set as INTERNET_OPEN_TYPE_PROXY. The default is NULL. pstrProxyBypass A pointer to a string containing an optional list of server addresses. These addresses may be bypassed when using proxy access. If a NULL value is supplied, the bypass list will be read from the registry. This parameter is meaningful only if dwAccessType is set to INTERNET_OPEN_TYPE_PROXY. dwFlags Indicates various options such as caching and asynchronous behavior. The default is set to 0. The possible values include: INTERNET_FLAG_DONT_CACHE Do not cache the data, either locally or in any gateway servers. INTERNET_FLAG_ASYNC Future operations on this object may fail with ERROR_IO_PENDING. A status callback will be made with INTERNET_STATUS_REQUEST_COMPLETE when the operation finishes. This callback is on a thread other than the one for the original request. You must call EnableStatusCallback to establish a status callback routine, or the functions will be completed synchronously. INTERNET_FLAG_OFFLINE Download operations are satisfied through the persistent cache only. If the item does not exist in the cache, an appropriate error code is returned. This flag may be combined with the bitwise OR (|) operator. CFtpConnection( ); Remarks This member function is called to construct a CFtpConnection object. You never create a CFtpConnection object directly. Instead, call CInternetSession::GetFtpConnection, which creates the CFptConnection object CFtpFileFind( CFtpConnection* pConnection, DWORD dwContext = 1 ); pConnection A pointer to a CFtpConnection object. You can obtain an FTP connection by calling CInternetSession::GetFtpConnection. The context identifier for the CFtpFileFind object. See Remarks for more information about this parameter. This member function is called to construct a CFtpFileFind object. BOOL GetFile( LPCTSTR pstrRemoteFile, LPCTSTR pstrLocalFile, BOOL bFailIfExists = TRUE, DWORD dwAttributes = FILE_ATTRIBUTE_NORMAL, DWORD dwFlags = FTP_TRANSFER_TYPE_BINARY, DWORD dwContext = 1 ); Return Value Nonzero if successful; otherwise 0. If the call fails, the Win32 function GetLastError may be called to determine the cause of the error. pstrRemoteFile A pointer to a null-terminated string containing the name of a file to retrieve from the FTP server. pstrLocalFile A pointer to a null-terminated string containing the name of the file to create on the local system. bFailIfExists Indicates whether the file name may already be used by an existing file. If the local file name already exists, and this parameter is TRUE, GetFile fails. Otherwise, GetFile will erase the existing copy of the file. dwAttributes Indicates the attributes of the file. This can be any combination of the following FILE_ATTRIBUTE_* flags. FILE_ATTRIBUTE_ARCHIVE The file is an archive file. Applications use this attribute to mark files for backup or removal. FILE_ATTRIBUTE_COMPRESSED The file or directory is compressed. For a file, compression means that all of the data in the file is compressed. For a directory, compression is the default for newly created files and subdirectories. FILE_ATTRIBUTE_DIRECTORY The file is a directory. FILE_ATTRIBUTE_NORMAL The file has no other attributes set. This attribute is valid only if used alone. All other file attributes override FILE_ATTRIBUTE_NORMAL: FILE_ATTRIBUTE_HIDDEN The file is hidden. It is not to be included in an ordinary directory listing. FILE_ATTRIBUTE_READONLY The file is read only. Applications can read the file but cannot write to it or delete it. FILE_ATTRIBUTE_SYSTEM The file is part of or is used exclusively by the operating system. FILE_ATTRIBUTE_TEMPORARY The file is being used for temporary storage. Applications should write to the file only if absolutely necessary. Most of the file’s data remains in memory without being flushed to the media because the file will soon be deleted. Specifies the conditions under which the transfer occurs. This parameter can be any of the dwFlags values described in FtpGetFile in the Platform SDK. The context identifier for the file retrieval. See Remarks for more information about dwContext. BOOL PutFile( LPCTSTR pstrLocalFile, LPCTSTR pstrRemoteFile, DWORD dwFlags = FTP_TRANSFER_TYPE_BINARY, DWORD dwContext = 1 ); A pointer to a string containing the name of the file to send from the local system. A pointer to a string containing the name of the file to create on the FTP server. Specifies the conditions under which the transfer of the file occurs. Can be any of the FTP_TRANSFER_* constants described in OpenFile. The context identifier for placing the file. See Remarks for more information about dwContext. virtual BOOL FindNextFile( ); Nonzero if there are more files; zero if this is the last file, and the previous call to either FindFile or FindNextFile returned nonzero. To get extended error information, call the Win32 function GetLastError.
27
类、函数表单: CInternetSession GetFtpConnection()
用于建立连接(使用该函数时要进行异常处理) CFtpFileFind(包括两虚成员函数FindFile()和FindNextFile()) 用于建立文件查找类 GetFile() 用于下载文件 PutFile() 用于上传文件 FindNextFile() 用于查找下一个文件,与 CFtpFileFind::FindFile()配合使用;
28
主要步骤: 举例说明一下一些函数的使用 1、创建一个INTERNET会话( CInternetSession())
2、建立与FTP服务器的连接——CFtpConnection对象 如果连接成功,获得当前登陆的缺省目录下所有的文件和目录名称,即如何检索某一个目录下的文件,并显示文件信息 3、下载文件或上传文件 4、关闭连接 举例说明一下一些函数的使用
29
实验二界面样例 CInternetSession sess(_T(“MyProgram/1.0”)); //建立会话
CFtpConnection* pConnect = NULL; try //需要进行异常处理 { //建立ftp连接 pConnect = sess.GetFtpConnection(_T("ftp.microsoft.com")); //创建CFtpFileFind对象 //利用函数FindFile()以及FindNextFile()查找并显示所有文件 CFtpFileFind finder(pConnect); BOOL bWorking = finder.FindFile(_T("*")); while (bWorking) { bWorking = finder.FindNextFile(); printf("%s\n", (LPCTSTR) finder.GetFileURL()); } } catch (CInternetException* pEx) //注意异常类型 { TCHAR sz[1024]; pEx->GetErrorMessage(sz, 1024); printf("ERROR! %s\n", sz); pEx->Delete(); CInternetSession( LPCTSTR pstrAgent = NULL, DWORD dwContext = 1, DWORD dwAccessType = INTERNET_OPEN_TYPE_PRECONFIG, LPCTSTR pstrProxyName = NULL, LPCTSTR pstrProxyBypass = NULL, DWORD dwFlags = 0 ); CFtpConnection* GetFtpConnection( LPCTSTR pstrServer, LPCTSTR pstrUserName = NULL, LPCTSTR pstrPassword = NULL, INTERNET_PORT nPort = INTERNET_INVALID_PORT_NUMBER, BOOL bPassive = FALSE ); 实验二界面样例
30
返回
31
实验四:聊天工具 实验目的 实验内容及要求 实验步骤 注意事项
32
实验目的 在前面两个实验的基础上进一步了解网络编程的过程。 掌握Windows环境下基于WinSock的编程方法和通讯实现。
编写一个聊天程序,即以客户端和服务器的模式进行互发消息。 back
33
实验内容及要求 利用MFC中的CAsyncsocket类已经集成了socket的基本函数,我们可以直接使用其成员函数来建立,初始化并应用socket,利用客户端和服务器模式,编写一个点对点的,可以相互发送和接收消息的程序,也就是常说的聊天工具。 该工具具有既可以作为服务器也可以做为客户端使用。 当作为服务器时要具有能输入自己的IP值和端口值,并能进行在线监听是否有客户端要求连接,如果有,还要能进行适当的响应,也就是接受连接请求建立连接,并实现消息互发。 当作为客户端是,要求能输入远地服务器的IP值和端口数,并进行连接请求,等待远地服务器的响应,当连接上后要能与服务器进行互发消息,聊天结束后还要实现与服务器的断开的功能。 back
34
实验步骤(1) 建立自己的socket类 使用MFC 中的CAsyncsocket类作为基类重载虚拟函数建立自己的socket类。 Eg.:class CMySocket : public CAsyncSocket 然后重载函数 void CMySocket::OnAccept() void CMySocket::OnClose() void CMySocket::OnConnect() void CMySocket::OnReceive() 这些函数系统会在有网络消息的时候自动调用它们,在下面的实验步骤(2)中提到要使用的函数就是在这些重载函数中调用的。(例子)我们还可以在这些函数中加入自己的代码,实现自己想要得功能。 最后还要在这个类中加入一个指向对话框类的指针作为成员变量,我们就是利用这个对话框类的成员函数来重载上面的虚拟函数的。
35
实验步骤(2) •建立客户端的 Socket :调用 socket() 函数 使用的函数 服务器端: 客户端:
•绑定端口:调用成员函数bind()函数 (注:对于MFC编程我们只要调用Create()函数就可以包括上面的两个函数) • 监听:调用成员函数listen()函数 • 服务器端接受客户端的连接请求:调用成员函数accept() 函数 •结束 socket 连接 :调用成员函数closesocket() 客户端: •建立客户端的 Socket :调用 socket() 函数 (注:我们也是调用Create()函数来完成Socket的建立的) • 提出连接申请 :调用成员函数connect()函数 以上这些函数我们是在重载前面的虚拟函数时使用的,例如OnAccept()函数中调用accept() 函数等等。
36
实验步骤(3) 界面例子 制作界面对话框类 List box,用于显示已发出和已接收的消息。
使用的控件: List box,用于显示已发出和已接收的消息。 Combo box(or Radio button),用于模式选择,客户机或服务器。 Edit box,用于输入IP和端口。 Button,控制命令按钮。 注意:要在对话框类中添加两个我们自己的socket类作为成员变量。因为当作为服务器时要有两个套接字。一个用于侦听连接请求,一个用于被连接到另一个应用程序。当然作为客户机时只要一个套接字就可以了。 界面例子 back
37
创建工程时别忘了CWinApp::InitInstance ()函数中调用这个函数来初始化
注意事项(1) 两个MFC函数 BOOL AfxSocketInit( WSADATA* lpwsaData = NULL );这个函数中调用::WSAStartup在你的程序退出的时候自动调用::WSACleanup int WSAAsyncSelect( SOCKET s, HWND hWnd, unsigned int wMsg, long lEvent ); 当有网络事件发生时系统会通知窗口并调用对应的函数。我们要做的就是重载这些回调函数,加入我们要的指令实现我们要的功能。 创建工程时别忘了CWinApp::InitInstance ()函数中调用这个函数来初始化 WSAAsyncSelect():要求某一 Socket 有事件 (event) 发生时通知使用者。 说明: 此函数用来请求 Windows Sockets DLL 为窗口句柄发一条消息-无论它何时检 测到由 lEvent 参数指明的网络事件。要发送的消息由 wMsg 参数标明.被通知的套接口由 s3网络实验 标识。本函数自动将套接口设置为非阻塞模式。
38
注意事项(2) 消息发送函数int Send( const void* lpBuf, int nBufLen, int nFlags = 0 ); 在使用这个函数之前要先判断消息发送编辑框是否有消息,如果是空则不发送,用CString.IsEmpty()函数进行判断,当不为空的时候返回0,否则返回非0。当发送函数调用成功时返回发送数据的长度,否则返回SOCKET_ERROR. 消息接受函数Receive( void* lpBuf, int nBufLen, int nFlags = 0 ); 当该函数调用成功时返回接收到的数据的长度,否则返回SOCKET_ERROR。我们可以事先分配一个大小为1025的数组用来缓存接收数据,当接收成功后要在这个数组最后加上NULL,即字符串的结束符,并将之转化为字符串类型,然后就可以使之在列表框中显示了。
39
注意事项(3) 实现控件的禁用和启用函数EnableWindow(TRUE/FALSE),这个函数在我们这个实验中经常用到,使用这个函数我们就可以实现当程序在某种状态下禁止一些不相关的控件的使用,这样就可以避免用户的一些不必要的误操作。 back
40
网络消息 意义 调用相应的函数 FD_READ 欲接收读准备好的通知 FD_WRITE 欲接收写准备好的通知 FD_ACCEPT
CAsyncSocket::OnReceive FD_WRITE 欲接收写准备好的通知 CAsyncSocket::OnSend FD_ACCEPT 欲接收将要连接的通知 CAsyncSocket::OnAccept FD_CONNECT 欲接收已连接好的通知 CAsyncSocket::OnConnect FD_CLOSE 欲接收套接口关闭的通知 CAsyncSocket::OnClose back
41
back
42
back
43
back
44
back
45
实验五、六:设计协议 实验内容:在Windows网络环境下,以其中的2台计算机为对象,构成主从计算机应用系统,设计简单的应用层协议,开发基于TCP/IP或UDP/IP的网络通信程序,实现数据传送和文件传输。 实验要求:正确理解应用层协议的概念;更深入了解客户/服务器模式的网络编程设计。 实验步骤及所需函数:参考实验二、三、四。
46
基于TCP的SOCKET编程 服务器端 1:创建套接字(socket) 2:将套接字绑定到一个本地地址和端口上(bind)
3:将套接字设为监听模式,准备接受客户请求(listen) 4:等待客户请求到来;请求到来后,接受请求,返回一个新的对应于此次连接的套接字(accept) 5:用返回的套接字和客户端进行通信(send/recv) 6:返回,等待另一客户请求 7:关闭套接字
47
客户端 1:创建套接字(socket) 2:向服务器发出连接请求(connect) 3:和服务器进行通信(send/recv) 4:关闭套接字
48
基于UDP的socket编程 服务器端 1:创建套接字(socket) 2:将套接字绑定到一个本地地址和端口上(bind)
3:等待接收数据(recvfrom) 4:关闭套接字
49
客户端 1.创建套接字(socket) 2.向服务器发送数据(sendto) 3.关闭套接字
50
Thank you!
Similar presentations