Socket网络编程.doc_第1页
Socket网络编程.doc_第2页
Socket网络编程.doc_第3页
Socket网络编程.doc_第4页
Socket网络编程.doc_第5页
已阅读5页,还剩16页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

XX大学实验报告学院:计信学院 专业:软件工程 班级: 姓名 学号 实验组实验时间2011-12-10指导教师 成绩实验项目名称 Socket网络编程实验目的1. 熟悉VisualC+的基本操作。2. 基本了解基于对话框的windows应用程序的编写过程。3. 对于Windows Socket编程建立初步概念。实验要求 1、了解基于对话框的windows应用程序的编写过程。 2、对于Windows Socket编程建立初步概念。实验原理一、Windows Socket和套接口的基本概念套接口,就是一个指向传输提供者的句柄。Win32中,套接口不同于文件描述符,所以它是一个独立的类型SOCKET。Windows Sockets描述定义了一个Microsoft Windows的网络编程界面,它是从 Unix Socket 的基础上发展而来的,为 Windows TCP/IP 提供了一个 BSD型的套接字规范,除与 4.3BSD Unix Sockets完全兼容外,还包括一个扩充文件,通过一组附加的 A PI实现 Windows 式(即事件驱动)的编程风格;而Winsock则是在Microsoft Windows 中进行网络应用程序设计的接口。Windows在Internet支配域中的TCP/IP协议定义了Winsock网络编程规范,融入了许多新特点。使用Socket的目的是使用户在网络协议上工作而不必对该网络协议有非常深入的了解。此外,编写的程序还可被迅速地移植到任何支持Socket的网络系统中去。Winsock提供了一种可为指定传输协议打开、计算和关闭会话的能力。在Windows下,TCP/IP上层模型在很大程度上与用户的Winsock应用有关;换言之,用户的Winsock应用控制了会话的方方面面,必要时,还会根据程序的需要格式化数据。套接口有三种类型:流式套接口、数据报套接口及原始套接口。流式套接口定义了一种可靠的面向连接的服务(利用TCP协议),实现了无差错无重复的顺序数据传输。数据报套接口定义了一种无连接的服务(UDP协议),数据通过相互独立的报文进行传输,是无序的,并且不保证可靠和无差错。原始套接口允许对低层协议如IP或ICMP直接访问,主要用于新的网络协议实现的测试等。套接口工作过程如图7.1所示:图7.1 套接口工作过程服务器首先启动,通过调用socket()建立一个套接口,然后调用bind()将该套接口和本地网络地址联系在一起,再调用listen()使套接口做好侦听的准备,并规定它的请求队列的长度,之后,调用accept()来接收连接。客户在建立套接口后就可调用connect()和服务器建立连接。连接一旦建立,客户机和服务器之间就可以通过调用send()和recv()(或read()和write())来发送和接收数据。最后,待数据传送结束后,双方调用close()关闭套接口。在网络编程中,掌握端口的概念十分重要。端口:基于TCP/IP协议的网络中,计算机都分配有一个IP地址,用一个32位二进制数来表示,正式的称呼是“Ipv4地址”。客户机需要通过TCP或UDP和服务器通信时,必须指定服务器的IP地址和服务端口号。另外,服务器打算侦听接入客户机请求时,也必须指定图1.2一个IP地址和一个端口号。在选择端口时,应特别小心,因为有些可用端口号是为“已知的”(即固定的)服务保留的,如文件传输协议和超文本传输协议,即FTP(21号端口)和HTTP(一般为8080端口)。“已知的协议”,即固定协议,采用的端口由“互联网编号分配认证(IANA)”控制和分配,RFC1700中说明的编号。从本质上说,端口号可分成3类:“已知”端口、已注册端口、动态和(或)私用端口。“已知”端口01023,由IANA控制,是在UNIX中为固定服务保留的。已注册的端口102449151,由IANA列出来的,供普通用户的普通用户进程或程序使用。 动态和(或)私用端口 4915265535。普通用户应用应选择102449151之间的已注册端口,从而避免端口号已被另一个应用或系统服务所用。此外,4915265535 间的端口可自由使用,因为IANA这些端口上没有注册服务。二、MFC对Socket编程的封装类简介Microsoft Windows Class Library(MFC)中提供了一些较高级封装的类用来实现网络通信。CAsyncSocket类封装了WindowsSockets API函数,提供了较低层的与Windows Sockets对话接口,一般适合于有相当水平的网络编程者使用,可方便地进行底层的网络事件通知及信息回叫控制等操作。CSocket类派生于CAsyncSocket,它继承了父类中一些常用易懂的Windows Sockets API函数,并对CAsyncSocket中底层的较难控制的一些API函数或成员函数进行了处理,使得网络传输简捷易用,同时它支持模块化的后台信息处理,解决了CAsyncSocket中较难克服的多线程处理。下面介绍用VisualC+在Windows中实现Socket的CSocket类型成员函数( 这些成员函数实际上是从CAsyncSocket类继承来的)。成员函数和参数说明:BOOL Create(UINT nSocketPort=0, int nSocketType =SOCK_STREAM,long lEvent=FD_READ|FD_WRITE|FD_OOB|FD_ACCEPT|FD _CONECT|FD_CLOSE,LPCTSTR lpszSocketAddress=NULL)该函数用来建立Socket,如果函数成功,则返回非零值;否则返回值为0。其中:nSocketPort:为所选择的Socket端口,一般要大于1023,如果该参数为0,则由系统选定一端口,默认值为0。nSocketType:为套接字类型SOCK_STREAM或SOCK_DGRAM。SOCK_STREAM表示为流套接字(本实验使用基于TCP连接的流套接字编程),SOCK_DGRAM表示为数据报套接字(将在以后实验中讲述),默认值为SOCK_STREAM。lEvent:标识该Socket要完成哪种工作,默认值为FD_READ|FD_WRITE|FD_OOB|FD_ACCEPT|FD_CONNECT|FD_CLOSE。lpszSockAddress:一个指向字符串的指针,该字符串包含了被连接套接口的网络地址。一个带点的数字,如“”,默认值为NULL。注意:CSocket中,Winsock API的初始化(socket)和绑定(bind)两部分工作都完成了。BOOL Listen (int nConnectionBacklog=5)该函数的作用是等待Socket请求,如果调用成功,则返回非零值;否则返回值为0。Listen仅对那些支持连接的套接字起作用,也就是SOCK_STREAM类型的套接字。在进程应答连接并把它放到等待队列时,套接字被置成被动模式(passive mode)。本函数一般由哪些一次可以有多个连接的服务器使用(或任何需要接收连接的应用)。nConnectionBacklog:表示等待队列的长度,默认值为最大值5,有效值为 15。 BOOL Connect(LPCTSTR lpszHostAddress,UINT nHostPort)该函数的作用是提出连接请求。其中:lpszHostAddress :对象连接的套接字的网络地址、机器名,如 ,或以句点分隔的数字,如“00”。nHostPort :为接受请求进程的网络地址和Socket端口号。注意:Connect函数还有另一个版本:BOOL Connect(const SOCKADDR *lpSockAddr,intnSockAddrLen);具体用法可以参阅MSDN Library 中关于CAnyscSocket类的阐述。virtual void Close()该函数的作用是关闭该Socket。实验环境 windows xp实验步骤1、先建立一个MFC,选dialogBased,工程名为LX1,要选择Window Sockets。出现Dialog以后,编辑界面,使其如上图所示。控件对应的变量如下表:控件ID变量名绑定变量类型对应界面上的控件IDC_CONTENTm_msgCStringt输入发送内容的文本框IDC_CONTENTm_ctrlCEdit输入发送内容的文本框IDC_CONNECTm_connectCButton连接按钮IDC_SEND m_sendCButton发送按钮 IDC_IPm_ipCString输入连接目的IP的文本框2、建立scocket 连结首先,Lx1工程里添加新类:CClient。继承自CSocket在CLx1Dlg类里添加private变量:CClient m_client;双击对话框图象上的“连接”按钮,添加代码:void CLx1Dlg:OnConnect() UpdateData(TRUE);m_client.Create(1001);/使用1001号端口if(m_client.Connect(m_ip, 1000)/连接目标地址,1000端口AfxMessageBox(Client端连接成功);m_send.EnableWindow(TRUE);/连接成功,可以发送m_connect.EnableWindow(FALSE);/同时禁止连接按钮elsem_client.Close();/如果连接失败就关闭AfxMessageBox(连接失败);双击发送按钮,添加代码:void CLx1Dlg:OnSend() UpdateData(TRUE);/更新数据,使m_msg得到当前框中文本m_client.Send(m_msg, 255);/发送数据,长度255字节3、添加接收聊天信息的函数。void CClient:OnReceive(int nErrorCode) / TODO: Add your specialized code here and/or call the base class(CLx1Dlg*)(AfxGetApp()-m_pMainWnd)-ShowMsg();CSocket:OnReceive(nErrorCode);void CLx1Dlg:ShowMsg()char buf255;m_client.Receive(buf, 255);/接收消息到buf里面,长度255字节。CString msg;msg.Format(%s, buf);AfxMessageBox(msg);/用AfxMessageBox函数显示接收到的字符窜。void CLx1Dlg:OnDestroy() CDialog:OnDestroy();m_client.Close();/关闭套接字4、收尾工作:即在对话框销毁的时候,关闭Socket连接,释放资源。void CLx1Dlg:OnDestroy() CDialog:OnDestroy();m_client.Close();/关闭套接字服务器端:1、先建立一个MFC,选dialogBased,工程名为LX2,要选择Window Sockets。出现Dialog以后,编辑界面,使其如上图所示。控件对应的变量如下表:控件ID变量名绑定变量类型对应界面上的控件IDC_CONTENTm_msgCString输入发送内容的文本框IDC_CONTENTm_ctrlCEdit输入发送内容的文本框IDC_LISTENm_listenCButton侦听按钮IDC_SENDm_sendCButton发送按钮2、建立scocket 连结首先,在BOOL CLx2Dlg:OnInitDialog()末尾添加语句,使其如下所示:m_send.EnableWindow(FALSE);/使发送按钮变灰return TRUE; / return TRUE 在lx2Dlg.h里添加头文件#include Server.hprivate变量:CServer m_server; CServer m_recv在对话框的图象上双击“侦听”按钮,在里面添加如下代码,使其如下所示:void CLx2Dlg:OnListen() m_server.Create(1000);/使用1000号端口m_server.Listen();/侦听在对话框图象上再双击“发送”按钮,添加代码,如下所示:void CLx2Dlg:OnSend() UpdateData(TRUE);/更新数据,使m_msg得到当前框中文本m_recv.Send(m_msg, 255);/发送数据m_ctrl.SetSel(0, -1);/全选发送框文字m_ctrl.ReplaceSel(, TRUE);/将发送框置空3、利用OnAccept和OnReceive函数处理socket消息。首先,在lx2工程的编辑界面点右键,选Class Wizard,在classname栏目里面找到CServer类,添加OnAccept和OnReceive函数并且双击下面的Member function栏目,分别为两个函数添加代码。void CServer:OnAccept(int nErrorCode)/ TODO: Add your specialized code here and/or call the base classCSocket:OnAccept(nErrorCode);(CLx2Dlg*)(AfxGetApp()-m_pMainWnd)-ShowAccept();/在这里仅仅添加了这一句,因为CLx2Dlg类是发送接收消息的主窗口,/而且应用程序发送接收的消息也在CLx2Dlg对象实例中进行,/所以当CServer类的对象收到客户机的Connect消息时,/便可调用CLx2Dlg对象中的ShowAccept() 函数处理。这步以后,可以为CLx2Dlg类里添加public成员函数ShowAccept()。void CLx2Dlg:ShowAccept()m_server.Accept(m_recv);AfxMessageBox(Server端连接成功);m_send.EnableWindow(TRUE);/连接成功,可以发送m_listen.EnableWindow(FALSE);/同时禁止侦听按钮于是,当客户机调用m_client.Connect(m_ip, 1000);这句时,主机server端发现,并调用ShowAccept函数来建立连接。执行完以后,Socket连接便被建立。4、添加发送聊天信息的函数。注意到前面点击发送按钮的OnSend() 函数已经添加好了,在Lx2工程中只要添加Server端的接收消息和显示消息功能就可以进行消息的传送。在CServer类里像添加OnAccept() 一样添加成员函数OnReceive()。void CServer:OnReceive(int nErrorCode) / TODO: Add your specialized code here and/or call the base classCSocket:OnReceive(nErrorCode);(CLx2Dlg*)(AfxGetApp()-m_pMainWnd)-ShowMsg();建立连接后,一方一旦发送数据,另一方的CSocket派生类便调用这个函数。其中代码可以参考前面OnAccept() 进行理解。在CLx2Dlg里添加成员函数ShowMsg()void CLx2Dlg:ShowMsg()char buf255;m_recv.Receive(buf, 255);/接收消息到buf里面,长度255字节。CString msg;msg.Format(%s, buf);/用AfxMessageBox函数显示接收到的字符窜。AfxMessageBox(msg);/这里注意CString类的用法实验内容利用Socket编写聊天程序。实验数据/ client.cpp : Defines the entry point for the console application./#include stdafx.h#include#include#include string.h#pragma comment(lib,WSOCK32.lib) /必须的#define PORT 5000 #define BUFFER 5000 WSADATA wsaData; SOCKET client; int port=PORT; /从服务器接收的数据长度 int iLen; /接受数据的缓冲 char bufBUFFER; /服务器端地址 struct sockaddr_in serv;DWORD WINAPI RecvThread(LPVOID lpParam) /从服务器接收数据 while(1) iLen=recv(client,buf,sizeof(buf),0); if(iLen=0) return 0; else if(iLen=SOCKET_ERROR) printf(recv()failed:%dn,WSAGetLastError(); return 0; else printf(Server send :%sn,buf); / int num=0; int sum=0; int i; for(i=0;i=strlen(buf);i+) if(bufi=0) num=num*10+bufi-0; continue; sum+=num; num=0; printf(The Sum is: %d .Now Send To Server.n,sum); sprintf(buf,%dnInput Data:,sum); int iSend=send(client,buf,sizeof(buf),0); /发送信息 if(iSend=SOCKET_ERROR) printf(send()failed:%dn,WSAGetLastError(); break; else printf(Send Okn); / return 0;void main(int argc,char *argv) /判断输入的参数是否正确 /*if(argc2) /注释掉了输入参数问题 /提书输入服务器IP地址 printf(Input the server IP address:n); return ; */接受数据缓冲区初始化 memset(buf,0,sizeof(buf); if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0) printf(Winsock load failedn); return; /需要连接的服务器地址信息 serv.sin_family=AF_INET; /需要连接的服务器地址信息 serv.sin_port=htons(port); /将命令行的IP地址转化为二进制表示的网络字节顺序IP地址 serv.sin_addr.s_addr=inet_addr(); /建立客户端流套接字 client=socket(AF_INET,SOCK_STREAM,0); if(client=INVALID_SOCKET) printf(socket()failed:%dn,WSAGetLastError(); return; /请求与服务器建立TCP连接 if(connect(client,(struct sockaddr*)&serv,sizeof(serv)=INVALID_SOCKET) printf(connet()failed:%dn,WSAGetLastError(); return; else HANDLE hThread; hThread=CreateThread(NULL,NULL,RecvThread,0,0,0); /创建接受信息线程 printf(Wait Server Send Data.n); while(1) /send data gets(buf); int iSend=send(client,buf,sizeof(buf),0); /发送信息 if(iSend=SOCKET_ERROR) printf(send()failed:%dn,WSAGetLastError(); break; / closesocket(client); WSACleanup(); printf(press any key to continue); /加了这两句,不让程序退出/下面是服务端/ sever.cpp : Defines the entry point for the console application./#include stdafx.h#include#include#include#include string.h#define PORT 5000#define BUFFER 1024#pragma comment(lib,WSOCK32.lib) /必须的int port=PORT;WSADATA wsaData;SOCKET sListen,sAccept;/客户地址长度int iLen;/发送数据长度int iSend;/需要发送的信息char bufBUFFER;/服务器、客户的地址struct sockaddr_in serv,cliet;DWORD WINAPI RecvThread(LPVOID lpParam) /static int i=0; /printf(%d,i+); while(1) /从服务器接收数据 iLen=recv(sAccept,buf,sizeof(buf),0); if(iLen=0) return 0; else if(iLen=SOCKET_ERROR) printf(recv()failed:%dn,WSAGetLastError(); return 0; else /printf(Client Send The Sum Back is:); printf(%s,buf); return 0;int main(int argc, char* argv) if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0) printf(Winsock load failedn); /return; /创建套接字 sListen=socket(AF_INET,SOCK_STREAM,0); if(sListen=INVALID_SOCKET) printf(socket failed:%dn,WSAGetLastError(); return; /建立服务器地址 serv.sin_family=AF_INET; /把一个双字节主机字节顺序的数据转换为网络字节顺序 serv.sin_port=htons(port); /把四字节主机字节顺序转换为网络字节顺序,INA

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论