孙鑫MFC(14)--网络编程
//-----------网络编程-----------------
//--------------服务器程序-------------
//所要包含的库文件
#include <Winsock2.h>
#include <stdio.h>
//需要在工程设置链接库中添加ws2_32.lib
1、套接字(socket)
//由美国伯克利大学在Unix上推出了一种应用程序访问通信协议的操作系统调用SOCKET,从而使程序员可以很方便地访问TCP/IP,开发出各种网络应用程序。
2、网络字节顺序
//不同的计算机存放多字节值的顺序不同,有是高位先存,有的低位先存
//在网络协议中需要制定网络字节顺序, TCP/IP协议使用16位整数和32位整数的高位先存格式
3、客户机/服务器模式
Client/Server
基于客户机/服务器模式的TCP/IP
4、Windows Sockets 的实现
从Berkeley Sockets扩展而来,对他进行了重要扩充,提供了一些异步函数,增加了符合消息驱动特性的网络事件异步选择机制。
三种套接字的类型
有链接及无连接的 Socket编程
二、示例
//---------------面向有链接的网络通信--------------------
1、加载套接字库
WSAStartup() //加载套接字库,并进行套接字库的版本协商(确定使用哪个版本的套接字库)
//下面代码来自帮助,演示了如何使用1.1版 的WinSock库
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 );
//相当于wVersionRequested = 0x101;
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
/* Tell the user that we could not find a usable */
/* WinSock DLL. */
//printf("找不到winsock.dll/n");
return;
}
/* Confirm that the WinSock DLL supports 1.1.*/
/* Note that if the DLL supports versions greater */
/* than 1.1 in addition to 1.1, it will still return */
/* 1.1 in wVersion since that is the version we */
/* requested. */
if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 ) {
/* Tell the user that we could not find a usable */
/* WinSock DLL. */
WSACleanup( );
return;
}
/* The WinSock DLL is acceptable. Proceed. */
//-----------------------------------------------------
SOCKET sockSrv = socket(AF_INET,SOCK_STREAM,0);
//对于TCP/IP协议的套接字,只能用AF_INET(PF_INET)地址族
//SOCK_STREAM基于TCP协议的套接字
//0为自动选择协议
if(scokSrv == SOCKET_ERROR)
{
printf("创建Sockets出错/n");
WSACleanup();
return;
}
SOCKADDR_IN addrSrv; //定义地址结构
addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY); //表示自动接收并发给任何地址
//htonl()函数表示转为网络字节序
addrSrv.sin_family = AF_INET; //指定地址族
addrSrv.sin_port = htons(6000); //指定端口号
//绑定本地地址及端口号
bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
listen(sockSrv,5) //监听,等待链接的最大数为5
SOCKADDR_IN addrClinet; //用于接收客户端套接字
int len = sizeof(SOCKADDR);
while(1)
{
//accept()函数,用于接受客户端发来的信息,并新创建一个符合客户端的套接字作为返回值
SOCKET sockConn = accept(sockSrv,(SOCKADDR*)&addrClinet,&len);
char sendBuf[100];
//将字符串信息格式化到发送缓存中
sprintf(sendBuf,"Welcome %s to my home",inet_ntoa(addrClinet.sin_addr));
//inet_ntoa()函数表示将in_addr结构体转为网络字节格式
send(sockConn,sendBuf,strlen(sendBuf) + 1,0);
//采用新建的套接字进行传送,加1是为了给发给客户端的信息加上'/0'介绍符
//最后个参数默认为0
char recvBuf[100];
int iRect;
//接收客户端信息
iRect = recv(sockConn,recvBuf,100,0);
recvBuf[iRect] = '/0';
//打印信息
printf("%s/n",recvBuf);
//关闭套接字
closesocket(sockConn);
}
//----------------------------------------------------
//==============客户端代码============
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
/* Tell the user that we could not find a usable */
/* WinSock DLL. */
return;
}
/* Confirm that the WinSock DLL supports 1.1.*/
/* Note that if the DLL supports versions greater */
/* than 1.1 in addition to 1.1, it will still return */
/* 1.1 in wVersion since that is the version we */
/* requested. */
if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 ) {
/* Tell the user that we could not find a usable */
/* WinSock DLL. */
WSACleanup( );
return;
}
/* The WinSock DLL is acceptable. Proceed. */
//---------------------------------
SOCKET sockClient = socket(AF_INET,SOCK_STREAM,0);
if(scokClient == SOCKET_ERROR)
{
printf("创建Sockets出错/n");
WSACleanup();
return;
}
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(6000);
if(SOCKET_ERROR == connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR)))
{
printf("链接服务器出错/n");
WSACleanup();
return;
}
/*
int iRect;
//接收客户端信息
iRect = recv(sockConn,recvBuf,100,0);
recvBuf[iRect] = '/0';
这一行代码不可少!因为recv函数不会自动将数据缓冲末尾
设为表示数据结束的空中止符(`/0`),因此,一不留神就会出现缓冲区越界。
当然也可以在调用recv函数前先将缓冲区清0(用ZeroMemory或memset),不过
还是建议加上这一句。*/
char recvBuf[100];
recv(sockConn,recvBuf,100,0);
printf("%s/n",recvBuf);
send(sockClient,"This is lisi",strlen("This is lisi") + 1,0);
closesocket(sockClient);
WSACleanup();
//-------------------------------------------------------------------------
//===========面向无连接的通信============
//--------服务器端---------------
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
/* Tell the user that we could not find a usable */
/* WinSock DLL. */
return;
}
/* Confirm that the WinSock DLL supports 1.1.*/
/* Note that if the DLL supports versions greater */
/* than 1.1 in addition to 1.1, it will still return */
/* 1.1 in wVersion since that is the version we */
/* requested. */
if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 ) {
/* Tell the user that we could not find a usable */
/* WinSock DLL. */
WSACleanup( );
return;
}
/* The WinSock DLL is acceptable. Proceed. */
//----------------------------------------------------------------
//无需循环监听,无需接受并单独创建套接字
SOCKET sockSrv = socket(AF_INET,SOCK_DGRAM,0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(6000);
bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
SOCKADDR_IN addrClient;
int len = sizeof(SOCKADDR);
char recvBuf[100];
recvfrom(sockSrv,recvBuf,100,0,(SOCKADDR*)&addrClient,&len);
printf("%s/n",recvBuf);
closesocket(sockSrv);
WSACleanup();
//------------------------客户端-----------------------------
#include <winsock2.h>
#include <stdio.h>
#pragma comment(lib,"ws2_32.lib");
void main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 );
//相当于wVersionRequested = 0x101;
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
/* Tell the user that we could not find a usable */
/* WinSock DLL. */
//printf("找不到winsock.dll/n");
return;
}
/* Confirm that the WinSock DLL supports 1.1.*/
/* Note that if the DLL supports versions greater */
/* than 1.1 in addition to 1.1, it will still return */
/* 1.1 in wVersion since that is the version we */
/* requested. */
if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 ) {
/* Tell the user that we could not find a usable */
/* WinSock DLL. */
WSACleanup( );
return;
}
/* The WinSock DLL is acceptable. Proceed. */
SOCKET sockClient = socket(AF_INET,SOCK_DGRAM,0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(6000);
sendto(sockClient,"Hello",strlen("Hello")+1,0,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
closesocket(sockClient);
WSACleanup();
}
//---------------------------------------------
以上转自:http://mxmkeep.blog.163.com/blog/
====================================================================================
1.加载套接字库
2.WSAStartup
The Windows Sockets WSAStartup function initiates use of Ws2_32.dll by a process.
int WSAStartup(
WORD wVersionRequested,
LPWSADATA lpWSAData
);
typedef struct WSAData {
WORD wVersion;
WORD wHighVersion;
char szDescription[WSADESCRIPTION_LEN+1];
char szSystemStatus[WSASYS_STATUS_LEN+1];
unsigned short iMaxSockets;
unsigned short iMaxUdpDg;
char FAR * lpVendorInfo;
} WSADATA, *LPWSADATA;
socket
The Windows Sockets socket function creates a socket that is bound to a specific service provider.
SOCKET socket(
int af,
int type,
int protocol
);
int bind(
SOCKET s,
const struct sockaddr FAR *name,
int namelen
);
struct sockaddr_in{
short sin_family;
unsigned short sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
Vc++6.0 error LNK2005: _main already defined in UdpClient.obj UDP时出现的问题
/**************************************************服务器端************************************************/
#include <Winsock2.h>
#include <stdio.h>
void main()
{
//加载套接字库,套接字库的版本协商 WSAStartup
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )
{
return;
}
if ( LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1 )
{
WSACleanup( );//终止套接字库的使用
return;
}
SOCKET sockSrv = socket(AF_INET,SOCK_DGRAM,0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(6000);
bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
char recvBuf[100];
char sentBuf[100];
char tempBuf[200];
SOCKADDR_IN addrClient;
int len = sizeof(SOCKADDR); //返回地址结构的长度
while (1)
{
recvfrom(sockSrv,recvBuf,100,0,(SOCKADDR*)&addrClient,&len); //接收地址(SOCKADDR*)&addrClient
if ('q'==recvBuf[0])
{
sendto(sockSrv,"q",strlen("q")+1,0,(SOCKADDR*)&addrClient,len); //发送地址
printf("Chat end!/n");
break;
}
sprintf(tempBuf,"%s say : %s",inet_ntoa(addrClient.sin_addr),recvBuf);//对方的IP地址addrClient.sin_addr
printf("%s/n",tempBuf);
printf("Please input data:/n");
gets(sentBuf);//从键盘上获取输入流
sendto(sockSrv,sentBuf,strlen(sentBuf)+1,0,(SOCKADDR*)&addrClient,len);
}
closesocket(sockSrv); //关闭套接字
WSACleanup(); //终止对套接字库的使用
}
/**************************************************客户端端************************************************/
#include <Winsock2.h>
#include <stdio.h>
void main()
{
//加载套接字库,套接字库的版本协商 WSAStartup
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )
{
return;
}
if ( LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1 )
{
WSACleanup( );//终止套接字库的使用
return;
}
SOCKET sockClient = socket(AF_INET,SOCK_DGRAM,0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(6000);
char recvBuf[100];
char sentBuf[100];
char tempBuf[200];
int len = sizeof(SOCKADDR); //返回地址结构的长度
while (1)
{
printf("Please input data:/n");
gets(sentBuf);//从键盘上获取输入流
sendto(sockClient,sentBuf,strlen(sentBuf)+1,0,(SOCKADDR*)&addrSrv,len);
recvfrom(sockClient,recvBuf,100,0,(SOCKADDR*)&addrSrv,&len);
if ('q'==recvBuf[0])
{
sendto(sockClient,"q",strlen("q")+1,0,(SOCKADDR*)&addrSrv,len);
printf("Chat end!/n");
break;
}
sprintf(tempBuf,"%s say : %s",inet_ntoa(addrSrv.sin_addr),recvBuf);
printf("%s/n",tempBuf);
}
closesocket(sockClient);
WSACleanup();
}
分享到:
相关推荐
该资源由内附孙鑫讲解的vc++编程1-20课的PPT讲解和详细实现代码,另附c++入门基础的课程,是每位c++编程爱好者必学的课程资源c++编程进阶的必经之路。
VC++深入详解教学视频(MFC)--荐 - - 2013-05-11 Visual C++灵感编程教学光盘 - - 2013-05-01 东南大学C++程序设计 - - 2013-05-04 从新手到高手C++全方位学习 - - 2013-04-04 吉林大学《C语言程序设计》 ...
在VS2012下用MFC写成的简易网络聊天室程序,包含的知识点有ODBC连接MySql数据库、CSocket类的运用等,对于mfc新手是个不错的学习资源(如果项目无法在VS2012下运行,有可能是因为VS版本不匹配(由于之前是先用VS2013...
C++编程小游戏,讲述c++MFC编程的内容,具体可借鉴孙鑫的MFC视频!
自学孙鑫的MFC深入详解,自行编写的MFC文本编程。适合初学MFC的同学参考。
最近正在学习C++,费了很多心思,分亨一下我的学习资源,孙鑫C++教程(全20讲)PPT讲义源码及电子书资源包括三部分 1.孙鑫C++教程PPT 2.孙鑫C++教程源码 3.孙鑫C++教程电子书 VC++深入详解的全部课程目录 第一课:...
编程语言枯燥难懂,然而通过孙鑫老师形象化的讲解,Windows和MFC编程中的难点、重点,让你轻松掌握。 3、实战性强 编程中要注意什么?如何阅读出错提示?如何调试运行程序?如何排查错误,解决问题?通过孙鑫...
此程序为本人在学习了孙鑫老师vc视频教程后,深彻领悟MFC编程原理和对比了Win32 SDK编程开发流程,经过本人不屑的努力,最终写成的,本人不断反思,探索思考而得,属于100%原创作品。 程序中隐藏WinMain函数,当成...
适用于使用过Win32 SDK的开发,进一步学习MFC的帮助性资料。
C程序设计语言_第2版新版、深入浅出 MFC_简体版.孙鑫VC++深入详解笔记、《高质量C++_C编程指南》
本书从实际应用入手,由浅入深、循序渐进地讲述Windows程序内部运行机制、MFC框架、文本、菜单、对话框、文件操作、网络编程、进程间通信、ActiveX控件、动态链接库、HOOK编程等多个主题。 本书内容丰富、实用性强...
学习孙鑫老师MFC编程时,自学笔记,内容很多,都是一些初学者常见的问题和一些关于windows应用程序基本原理的,希望对你有些帮助
虽然没有孙鑫老师的教材经典,但是确实英文经典翻译,是深入学习MFC的教程
《VC++深入详解》从实际应用入手,由浅入深、循序渐进地讲述Windows程序内部运行机制、MFC框架、文本、菜单、对话框、文件操作、网络编程、进程间通信、ActiveX控件、动态链接库、HOOK编程等多个主题。 《VC++...
Windows编程知识,VC++面向对象的编程思想,MFC编程,涵盖了软件开发中的绝大部分应用,以及在以后开发中可能出现的问题,由孙鑫老师一一帮你剖析。
实现了基本的聊天功能,代码注释较为详细,模仿孙鑫老师的编程思路。
1)包括MFC/Windows编程/GDI/多线程/同步/Socket 孙鑫老师的代表做,好好珍惜吧。
本文资源根据孙鑫《VC++深入详解》一书,详细的介绍了吗,程序内部运行的机制和MFC程序的组织脉络入手,使读者在学习VC++编程知识时,既能够知其然,又能知其所以然,从而帮助读者从根本上理解和掌握Windows的程序...
摘要:VC/C++源码,界面编程,菜单 孙鑫主讲的VC++菜单工作原理及编写应用,菜单命令消息在MFC框架程序的几个类中的传递顺序和处理过程。 标记菜单、缺省菜单的实现原理、图形菜单的实现及常犯错误的分析,...
内容索引:VC/C++源码,控件相关,动态链接库,DLL 孙鑫VC++中的dll动态链接库应用实例源码,本源码涉及动态链接库程序的编写以及静态库与动态库的区别说明,包括调用程序在链接静态库和动态库时的区别。如何利用工具...