各位大哥,我现在做毕业设计,要用到C/S这种模式进行通信,所以现在要急着学,请大家帮忙,给个这样的通信源代码给我,谢谢.
解决方案 »
- 求助!!高手请进!
- VC里上传功能的实现 ,速度比较好的
- 郁闷,散分!我想打开csdn的mfc版帖子总是空白页????大家有吗?请问csdn管理员怎么回事?????
- 如何响应CListCtrl标题栏右键事件
- 玉兰是怎么了?
- 关于指向数组成员的成员指针的疑惑~~~
- 急问菜鸟问题:如何将一个long型值转化为char*,最后再将char* 转化为long,要求准确无误,谢谢!
- 有关Tree控件!——初学者的问题
- 要交作业了,大家帮帮忙!!!
- MFC程序在VS调试模式下,CPropertySheet属性向导出现异常?求大神看看
- 关于客户端访问COM接口的问题!
- 关于图形重绘的问题,请高手指点(100分)
http://www.vckbase.com/document/viewdoc.asp?id=484
//
#include <stdafx.h>
#include <Winsock2.h>
#include <stdio.h>
#include <fstream.h>
#include <string>
#include <time.h>
void OnSaveData(char* buffer);
int main(int argc, char* argv[])
{
SOCKET socketid;
struct sockaddr_in server;
SOCKET msgsocket;
struct sockaddr client;
char buffer[50];
int rval; //进行协商
WORD wVersionRequested;
WSADATA wsaData;
int err;
//使要求的版本为1.1
wVersionRequested=MAKEWORD(1,1);
err=WSAStartup(wVersionRequested, &wsaData);
if (err!=0)
{
//用户没有找到一个可以使用的DLL,返回
perror("there is no DLL to use");
return 0;
}
//确保Windows Sockets DLL支持1.1。
if ( (LOBYTE(wsaData.wVersion)!=1) || (HIBYTE(wsaData.wVersion)!=1) )
{
perror("there is not right DLL");
WSACleanup();
return 1;
}
//建立Sockets
socketid=socket(AF_INET,SOCK_STREAM,0);
if (socketid==INVALID_SOCKET)
{
perror("there is error in opening sockets\n");
return 2;
}
//使用端口号5050来命名服务器的Sockets
server.sin_family=AF_INET;
server.sin_port=htons(5050);
server.sin_addr.S_un.S_un_b.s_b1=192;
server.sin_addr.S_un.S_un_b.s_b2=168;
server.sin_addr.S_un.S_un_b.s_b3=0;
server.sin_addr.S_un.S_un_b.s_b4=1; if ( bind(socketid, (sockaddr *)&server,sizeof(server))<0)
{
perror("there is error in binding sockets\n");
return 3;
}
//输出端口号
int length=sizeof(server);
if(getsockname(socketid,(struct sockaddr *)&server,&length)<0)
{
perror("there is error in getting name");
return 4;
}
printf("socket port %d\n",ntohs(server.sin_port));
//开始接收连接
listen(socketid,5);
//进入一个死循环
int len=sizeof(struct sockaddr);
do
{
msgsocket=accept(socketid,(struct sockaddr *)&client,(int*)&len);
if (msgsocket==INVALID_SOCKET)
{
perror("there is error in open new sockets");
break;
}
else do
{
memset(buffer,0,sizeof(buffer));
if ( (rval=recv(msgsocket,buffer,512,0))==-1 )
{
perror("there is error in recving");
break;
}
if (rval==0)
printf("ending connection\n");
else
{
OnSaveData(buffer);
printf("%s\n",buffer);
}
}while(rval!=0);
closesocket(msgsocket);
}while(TRUE); closesocket(socketid);
WSACleanup();
return 100;
}////////////////////////////////////////////////////////////
//数据存盘
void OnSaveData(char *buffer)
{
char strbuffer[256];
char strDate[256],strTime[256];
time_t time_current;
char strDir[256]="e:\\SaveData\\";
char strTxt[]=".txt";
char *strFilename;
time_current = time((time_t*)NULL);
//以“星期 月/日期/年”的格式"%a-%m-%d-%y"
strftime(strbuffer,sizeof(strbuffer),"%m-%d-",localtime(&time_current));
strcpy(strDate,strbuffer);
//以“时:分:秒”的格式
strftime(strbuffer,sizeof(strbuffer),"%H-%M",localtime(&time_current));
strcpy(strTime,strbuffer);
strcat(strDate,strTime);
strcat(strDate,strTxt);
strcat(strDir,strDate);
//strcat(strFilename,strDate);
strFilename=strDir; //printf("%s\n",strDate);
//printf("%s\n\n",strFilename);
ofstream myf(strFilename,std::ios::ate|std::ios::out);//if file isnot exit,then create it
myf<<buffer<<endl;}
/*
void printlocaltime(void)
{
struct tm * timeptr;
time_t secsnow;
time(&secsnow);
timeptr = localtime(&secsnow);
printf("The date is %d-%d-19%02d\n",(timeptr->tm_mon)+1,
(timeptr->tm_mday),(timeptr->tm_year));
printf("Local time is %02d:%02d:%02d\n",timeptr->tm_hour,
timeptr->tm_min,timeptr->tm_sec);
*/
//客户端的应用程序
//#include <winsock2.h>
#include <stdio.h>
#include <math.h>#include <windows.h> /* For the CreateThread prototype */
//using namespace std;
//#define DATA "hello,world!"
int count=0;
int sockid;
int connectid;VOID CALLBACK timer(
HWND hwnd, // handle of window for timer messages
UINT uMsg, // WM_TIMER message
UINT idEvent, // timer identifier
DWORD dwTime // current system time
)
{
char buffer[50];
double iData=10*sin(2*3.1415926*64*rand()/RAND_MAX);
_gcvt(iData,7,buffer);
if ((send(sockid,buffer,sizeof(buffer),0))<0)
{
perror("there is error in sending the data\n");
return;
}
else
{
printf("Sending successfully.\n");
}
return ;
}void main(argc,argv)
int argc;
char *argv[];
{
//int sockid; //socket号
struct sockaddr_in server_addr; //服务器的地址结构
struct hostent *hp; // 主机
MSG msg;
int send;
//////////以下代码是对socket版本号的处理////////////
//进行协商
WORD wVersionRequested;
WSADATA wsaData;
//使要求的版本为1.1
int err;
wVersionRequested=MAKEWORD(1,1);
err=WSAStartup(wVersionRequested, &wsaData);
if (err!=0)
{
//用户没有找到一个可以使用的DLL,返回
perror("there is no DLL to use");
return;
}
//确保Windows Sockets DLL支持1.1。
if ( (LOBYTE(wsaData.wVersion)!=1) || (HIBYTE(wsaData.wVersion)!=1) )
{
perror("there is not right DLL");
WSACleanup();
return;
}
///////////socket版本号处理完毕////////////
//建立Socket
sockid=socket(AF_INET,SOCK_STREAM,0);
if (sockid<0)
{
perror("there is error in opening stream socket,fuck you");
return;
}
//得到命令行中指定的名字连接socket
server_addr.sin_family=AF_INET;
hp=gethostbyname("chl");//argv[1]);
if(hp==0)
{
return;
}
memcpy((char *)&server_addr.sin_addr,(char *)hp->h_addr,hp->h_length);
server_addr.sin_port=htons(5050);//(unsigned short)atoi(argv[2]));
do
{
//进行连接
if(connectid=connect(sockid,(struct sockaddr*)&server_addr,sizeof(server_addr))<0)
{
perror("there is error in connecting stream socket");
//return;
}
}while(connectid<0);
printf("%d",connectid);
send=SetTimer(NULL,0,1000,(TIMERPROC)timer);
if(send)
printf("success\n");
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
KillTimer(NULL,send);
//进行发送数据
/*@**#---2003-05-04 20:58:18 (orbit)---#**@
if ((send(sockid,DATA,sizeof(DATA),0))<0)
{
perror("there is error in sending the data");
return;
}
else
{
printf("Sending successfully.");
}*/
//关闭socket
closesocket(sockid);
WSACleanup();
return;
}
个服务器与客户机互相传送消息的程序,以便增加自己网络编程的经验.下面
我就介绍一下我编的程序. ---- 首先介绍服务器程序: ---- 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 here
Isconnect=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....";
}
else
m_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\n";
pView->InvalidateRect(NULL);
}
else
{switch(msg[0])
{
case'A':
wsprintf(msg,"A: Client from %s
attached\n",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\n",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 here
char 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 here
pCmdUI->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 here
Isconnect=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 here
count=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....";
}
else
m_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 here
pCmdUI->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++网络编程的优点,你还可以添加其它功能项,在
这我就不多加叙述了.希望我的程序能起到抛砖引玉的目的,让我们都能编出好的网络程序.