用vc6.0编服务器与客户机互相传送消息的程序
用vc6.0编服务器与客户机互相传送消息的程序
----
南京理工大学 朱晓华---- 网络编程已经成为一种时髦,以TCP/IP协议的网络更为流行.自己编一个服务器与客户机互相传送消息的程序,以便增加自己网络编程的经验.下面我就介绍一下我编的程序.
---- 首先介绍服务器程序:
---- 1.创建一个名为"server"的项目,单文档界面.
---- 2.在serverview.h中加入代码:
#include "winsock.h" 添加变量:CSize sizeTotal;//控制滚动条intcount;//信息条数CString m_data[1000];//信息存放char Hostname[260];char Hostaddress[20];//主机IP地址SOCKET m_sock;HANDLE m_hListenThread;//线程BOOL m_bInitialized;//是否初始化WSADATAWSAData;BOOL flag;SOCKADDR_IN saClnt;int saClntLen;BOOL Isconnect;//是否连接
----
3.在serverview.cpp中重载CServerView()构造器,创建并绑定嵌套字:CServerView::CServerView(){// TODO: add construction code hereIsconnect=FALSE;flag=FALSE;sizeTotal.cy=350;sizeTotal.cx=300;m_hListenThread;count=5;int status;WSADATA wsaData;m_data[0]="initializing Windows Sockets DLL....";if((status=WSAStartup(0x0101,&wsaData))==0){m_data[0]+="Succeeded";m_bInitialized=TRUE;}else{m_bInitialized=FALSE;}m_sock=socket(AF_INET,SOCK_DGRAM,0);m_data[1]="Creating socket....";if(m_sock==INVALID_SOCKET){m_data[1]+="Failed";}m_data[1]+="Succeeded";m_data[2]="Binding socket....";sockaddr_in sa;sa.sin_family=AF_INET;sa.sin_addr.S_un.S_addr=htonl(INADDR_ANY);sa.sin_port=htons(5050);if(bind(m_sock,(PSOCKADDR)&sa,sizeof(sa))==SOCKET_ERROR){m_data[2]+="Failed";closesocket(m_sock);}m_data[2]+="Succeeded";m_data[3]="Creating listener thread....";unsigned long idThread;m_hListenThread=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)Listen,(void *)this,0,&idThread);if(m_hListenThread){m_data[3]+="Succeeded";m_data[4]+="Listening....";}elsem_data[4]+="Failed";}
----
4.在析构函数中完成必需的清除操作:CServerView::~CServerView(){if(m_bInitialized)WSACleanup();closesocket(m_sock);if(m_hListenThread)::TerminateThread(m_hListenThread,0);}
----
5.定义接收和处理消息的线程:long WINAPI Listen(CServerView *pView){char msg[2000]="";intnchar;SOCKADDR_IN saClnt;int saClntLen;while(1){saClntLen=sizeof(saClnt);nchar=recvfrom(pView->m_sock,msg,1024,0,(PSOCKADDR)&saClnt,&saClntLen);if(nchar<0) { pView->m_data[pView->count++]+="Error in recvfrom";pView->InvalidateRect(NULL);}else{switch(msg[0]){case'A':wsprintf(msg,"A: Client from %s attached",inet_ntoa(saClnt.sin_addr));pView->m_data[pView->count++]=msg;pView->flag=TRUE;pView->InvalidateRect(NULL);pView->Isconnect=TRUE;pView->saClnt=saClnt;pView->saClntLen=saClntLen;sendto(pView->m_sock,msg,1024,0,(PSOCKADDR)&saClnt,saClntLen);break;case 'D':wsprintf(msg,"D: Client form %s detached",inet_ntoa(saClnt.sin_addr));pView->m_data[pView->count++]=msg;pView->flag=TRUE;pView->InvalidateRect(NULL);pView->Isconnect=FALSE;sendto(pView->m_sock,msg,1024,0,(PSOCKADDR)&saClnt,saClntLen);break;case 'R':saClntLen=sizeof(saClnt);pView->m_data[pView->count++]=msg;pView->flag=TRUE;pView->InvalidateRect(NULL);break;default:break;}}}return(0);}
----
6.在程序菜单项中添加"本机IP地址":void CServerView::OnIp() {int WSAReturn;WSAReturn=WSAStartup( 0x0101, &WSAData );if( WSAReturn == 0 ){gethostname( Hostname, 260 );struct hostent *pHostEnt;pHostEnt = gethostbyname( Hostname);if( pHostEnt != NULL ){wsprintf( Hostaddress, "%d.%d.%d.%d",( pHostEnt->h_addr_list[0][0] & 0x00ff ),( pHostEnt->h_addr_list[0][1] & 0x00ff ),( pHostEnt->h_addr_list[0][2] & 0x00ff ),( pHostEnt->h_addr_list[0][3] & 0x00ff ) );CString out;out.Format(Hostaddress);AfxMessageBox(out);}}}
----
7.在程序菜单中添加"发送消息":void CServerView::OnSendmessage() {// TODO: Add your command handler code herechar msg[2000];Csend Sendmessage;if(Sendmessage.DoModal()==IDOK&&!Sendmessage.m_Message.IsEmpty()){wsprintf(msg,"R: "+Sendmessage.m_Message);sendto(m_sock,msg,1024,0,(PSOCKADDR)&saClnt,saClntLen);m_data[count++]=Sendmessage.m_Message;flag=TRUE;InvalidateRect(NULL);}}
----
8.为发送消息项添加一个对话框的类,名为send,有一个文本框,用来发送消息.并为文本框添加CString m_Message 变量,并在ServerView.cpp中添加#include "send.h"---- 9.为发送消息项添加一个判断函数:
void CServerView::OnUpdateSendmessage(CCmdUI* pCmdUI) {// TODO: Add your command update UI handler code herepCmdUI->Enable(FALSE);if(Isconnect)pCmdUI->Enable(TRUE);}
----
10.再窗口显示消息:void CServerView::OnDraw(CDC* pDC){if(flag){sizeTotal.cy+=20;for(int j=65;jTextOut(10,y,m_data[i]);y+=20;}// TODO: add draw code for native data here}
----
11.在Project中点击Settings中选择Link项添加wsock32.lib. 最后编译程序,就可以得到Server.exe程序.---- 现在介绍客户机程序:
---- 1.创建一个名为"client"的项目,单文档界面.
---- 2.在clientview.h中加入代码:
#include "winsock.h"添加变量:CString m_data[1000];HANDLE m_hListenThread;SOCKET m_sock;SOCKADDR_IN m_saSrvr;BOOLIsconnect;int count;CSize sizeTotal;BOOLflag;
----
3.在构造函数中初始化变量:CClientView::CClientView(){// TODO: add construction code hereIsconnect=FALSE;sizeTotal.cy=350;sizeTotal.cx=300;flag=FALSE;}
----
4.在析构函数中完成清除操作:CClientView::~CClientView(){if(m_bInitialized)WSACleanup();closesocket(m_sock);if(m_hListenThread)::TerminateThread(m_hListenThread,0);}
----
5.在菜单中添加"拨号"项:void CClientView::OnDial() {// TODO: Add your command handler code herecount=5;if(m_bInitialized){AfxMessageBox("Already dialing");return;}Cdial dial;if(dial.DoModal()==IDOK&&!dial.m_HostAddress.IsEmpty()){m_saSrvr.sin_family=AF_INET;m_saSrvr.sin_addr.S_un.S_addr=htonl(INADDR_ANY);m_saSrvr.sin_addr.S_un.S_addr=inet_addr(dial.m_HostAddress);m_saSrvr.sin_port=htons(5050);int status;WSADATA wsaData;m_data[0]="initializing Windows Sockets DLL....";if((status=WSAStartup(0x0101,&wsaData))==0){m_data[0]+="Succeeded";m_bInitialized=TRUE;}else{m_bInitialized=FALSE;}m_sock=socket(AF_INET,SOCK_DGRAM,0);m_data[1]="Creating socket....";if(m_sock==INVALID_SOCKET){m_data[1]+="Failed";}m_data[1]+="Succeeded";m_data[2]="Binding socket....";sockaddr_in sa;sa.sin_family=AF_INET;sa.sin_addr.S_un.S_addr=htonl(INADDR_ANY);sa.sin_port=htons(0);if(bind(m_sock,(PSOCKADDR)&sa,sizeof(sa))==SOCKET_ERROR){m_data[2]+="Failed";closesocket(m_sock);}m_data[2]+="Succeeded";m_data[3]="Creating listener thread....";unsigned long idThread;m_hListenThread=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)Listen,(void *)this,0,&idThread);if(m_hListenThread){m_data[3]+="Succeeded";m_data[4]+="Waiting....";}elsem_data[4]+="Failed";InvalidateRect(NULL);}}
----
6.添加一个拨号对话框,名为dial,有一个文本框用来写IP地址.并在clientview.cpp中添加代码:#include dial.h
----
7.在拨号项添加一个判断函数:void CClientView::OnUpdateDial(CCmdUI* pCmdUI) {// TODO: Add your command update UI handler code herepCmdUI->Enable(TRUE);if(Isconnect)pCmdUI->Enable(FALSE);}
----
8.添加接收与发送消息的线程:long WINAPI Listen(CClientView *pView){char msg[2000];pView- >m_data[5]="Sending ATTACH command";pView- >InvalidateRect(NULL);wsprintf(msg,"A: ");sendto(pView- >m_sock,msg,1024,0,(PSOCKADDR)&pView- >m_saSrvr,sizeof(pView- >m_saSrvr));int saSrvrLen ,nchar;while(1){saSrvrLen=sizeof(pView->m_saSrvr);nchar=recvfrom(pView- >m_sock,msg,1024,0,(PSOCKADDR)&pView- >m_saSrvr,&saSrvrLen);if(nchar<0) { pView->m_data[pView- >count++]="Error in recvform";pView- >InvalidateRect(NULL);}else{pView->m_data[pView- >count++]=msg;pView->Isconnect=TRUE;pView->flag=TRUE;pView->InvalidateRect(NULL);}}return(0);}
----
9.同主程序一样做一个发送消息项,代码如上.---- 10.显示程序也与主程序一样,代码如上.
---- 11.在Project中点击Settings中选择Link项添加wsock32.lib.
---- 12.编译程序便可得到client.exe程序.
---- server.exe 和 client.exe 做完后,就可以在具有TCP/IP协议下的网络中执行. 通过上面的例子,你可以很快了解vc++网络编程的优点,你还可以添加其它功能项,在这我就不多加叙述了.希望我的程序能起到抛砖引玉的目的,让我们都能编出好的网络程序.
Tags:
作者:佚名评论内容只代表网友观点,与本站立场无关!
评论摘要(共 0 条,得分 0 分,平均 0 分)
查看完整评论