Vc网络编程应用
一、 基于TCP IP
客户端程序:
要加载ws2_32.lib
#include <Winsock2.h>
#include <stdio.h>
void main()
{
WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD( 1, 1);
int err =WSAStartup( wVersionRequested, &wsaData ); //加载套接字字库
if ( err != 0 ) { return; }
if (LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1 )
{
WSACleanup( );
return;
}
SOCKETsockClient=socket(AF_INET,SOCK_STREAM,0); //创建套接字
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=inet_addr("202.197.156.55");
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);//将要分配给套接字端口
connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));//发出连接请求
charrecvBuf[100];
recv(sockClient,recvBuf,100,0); //接收数据
printf(“%s\n”,recvBuf);
send(sockClient,”thisis my!”,sizeof(“this is my!”)+1,0); //发送数据
closesocket(sockClient); //关闭套接字
WSACleanup(); //关闭套接字库
//本地回路地址,不管本地主机上有没有网卡,都可以测试网络
//TCP和UDP编程代码大致相同,不同之处在于,TCP使用send/recv;UDP使用sendto/recvfrom;TCP发送之前已经连接,所以send函数不用之处发送的地址
服务器端程序:
#include <Winsock2.h>
#include <stdio.h>
void main()
{
WORDwVersionRequested;
WSADATAwsaData;
wVersionRequested= MAKEWORD( 1, 1);
int err =WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )
{ return;}
if ( LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1 )
{
WSACleanup( );
return;
}//如果不是请求的win32版本就返回
//创建套接字
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)); //保定端口
listen(sockSrv,5);///设置为监听模式 //
SOCKADDR_IN addrClient;//接收实体的地址
int len=sizeof(SOCKADDR);
while(1) {
SOCKET sockConn=accept(sockSrv,
(SOCKADDR*)&addrClient,
&len //返回包含地址信息的长度
);
The accept functionextracts the first connection on the queue of pending connections on socket s. It then creates a new socket andreturns a handle to the new socket
char sendBuf[100];
sprintf(sendBuf,"Welcome %s tohere",inet_ntoa(addrClient.sin_addr));
send(sockConn,sendBuf,strlen(sendBuf)+1,0);///发送数据
char recvBuf[100];
memset(recvBuf,0,100);
recv(sockConn,recvBuf,100,0);///接收数据
printf("%s\n",recvBuf);
closesocket(sockConn);//关闭
}
二、基于UDP
TCP和UDP编程代码大致相同,不同之处在于,TCP使用send/recv;UDP使用sendto/recvfrom;
且无需连接
客户端程序
#include <Winsock2.h>
#include <stdio.h>
void main()
{
WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD( 1, 1);
int err =WSAStartup( wVersionRequested, &wsaData ); //加载套接字字库
if ( err != 0 ) { return; }
if (LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1 )
{
WSACleanup( );
return;
}
SOCKETsockClient=socket(AF_INET,SOCK_STREAM,0); //创建套接字
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=inet_addr("202.197.156.55");
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);//将要分配给套接字端口
//connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));//不需连接
charrecvBuf[100];
recvfrom(sockClient,recvBuf,100,0); //接收数据
printf(“%s\n”,recvBuf);
sendto(sockClient,”thisis my!”,sizeof(“this is my!”)+1,0); //发送数据
closesocket(sockClient); //关闭套接字
WSACleanup(); //关闭套接字库
服务器端程序
#include <Winsock2.h>
#include <stdio.h>
void main()
{
WORDwVersionRequested;
WSADATAwsaData;
wVersionRequested= MAKEWORD( 1, 1);
int err =WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )
{ return;}
if ( LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1 )
{
WSACleanup( );
return;
}//如果不是请求的win32版本就返回
//创建套接字
SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,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)); //任需绑定端口
//listen(sockSrv,5);///不需设置为监听模式 //
SOCKADDR_IN addrClient;//接收实体的地址
int len=sizeof(SOCKADDR);
while(1) {
//SOCKET sockConn=accept(sockSrv,
(SOCKADDR*)&addrClient,
&len //返回包含地址信息的长度
); //不需
char sendBuf[100];
char recvBuf[100];
memset(recvBuf,0,100);
recvfrom(sockConn,recvBuf,100,0,(SOCKDDR *)addrClient,&len);///接收数据
printf("%s\n",recvBuf);
closesocket(sockConn);//关闭
}
三、 基于异步套接字
初始化
wVersionRequested = MAKEWORD( 2,2 );
err = WSAStartup(wVersionRequested, &wsaData );
if ( err != 0 ) {
return FALSE;
}
if ( LOBYTE( wsaData.wVersion )!= 2 ||
HIBYTE( wsaData.wVersion ) != 2 ) {
WSACleanup( );
return FALSE;
}
m_socket=WSASocket(AF_INET,SOCK_DGRAM,0,NULL,0,0);//创建套接字非重叠方式
if(INVALID_SOCKET==m_socket)
{
MessageBox("创建套接字失败!");
return FALSE;
}
缓冲区要调大
int send_size=204800;
setsockopt(m_socket,SOL_SOCKET,SO_SNDBUF,(char *)&send_size,4);
//addrSock.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
addrSock.sin_family=AF_INET;
addrSock.sin_port=htons(6000);
addrSock.sin_addr.S_un.S_addr=inet_addr("202.197.156.51");
if(SOCKET_ERROR==bind(m_socket,(SOCKADDR*)&addrSock,sizeof(SOCKADDR)))
{
MessageBox("绑定失败!");
return FALSE;
}
if(SOCKET_ERROR==WSAAsyncSelect(m_socket,m_hWnd,UM_SOCK,FD_READ))//注册读取事件
{
事件发生时指定的消息名称 |
return FALSE;
}
添加消息响应
void CChatDlg::OnSock(WPARAMwParam,LPARAM lParam)
{
switch(LOWORD(lParam))
{
case FD_READ:
WSABUF wsabuf;
wsabuf.buf=new char[200];
wsabuf.len=200;
DWORD dwRead;
DWORD dwFlag=0;
SOCKADDR_IN addrFrom;
int len=sizeof(SOCKADDR);
CString str;
CString strTemp;
HOSTENT *pHost;
if(SOCKET_ERROR==WSARecvFrom(m_socket,&wsabuf,1,&dwRead,&dwFlag,
(SOCKADDR*)&addrFrom,&len,NULL,NULL))
{
MessageBox("接收数据失败!");
return;
}
第二个参数是结构体数组的指针
pHost=gethostbyaddr((char*)&addrFrom.sin_addr.S_un.S_addr,4,AF_INET);
//str.Format("%s说:%s",inet_ntoa(addrFrom.sin_addr),wsabuf.buf);
str.Format("%s说:%s",pHost->h_name,wsabuf.buf);
str+="\r\n";
GetDlgItemText(IDC_EDIT_RECV,strTemp);
str+=strTemp;
SetDlgItemText(IDC_EDIT_RECV,str);
break;
}
}
四、 利用MFC提供的类
工程中添加CasyncSocket是子类 就无需添加消息响应和各初始化函数 直接重载就行
服务器端
1、 添加CasyncSocket子类
2、 在stdafx.h中添加
#include<afxsock.h>
3、 在InitInstance中添加
AfxSocketInit();//初始化MFC套接字库 只能加载1.1版本的 2.0的要用WSAStartup
4、 初始化
CMySock* mysock= new CMySock;
if(mysock->Create(7000))//创建端口,并绑定到端口,该函数默认创建SOCK_STREAM(TCP IP)
{
MessageBox("套接字创建成功!");
}
mysock->AsyncSelect(FD_READ| FD_ACCEPT );
mysock->Listen();
5、 重载个虚函数
客户端
由于大多不需要绑定端口,用传统的 socket(AF_INEF,SOCK_STREAM,0);
TCP发送之前已经连接,所以send函数不用之处发送的地址
Cose MFC 基于对话框
编辑框用来接收数据
编辑框1 IDC_EDIT_REC
编辑框2IDC_EDIT_SEND
按钮 IDC_BUT_SEND
2 加载套接字库
//加载套接字库
if(!AfxSocketInit())
{
AfxMessageBox("加载套接字库失败!");
return false;
}
在StdAfx.h中添加包含头文件
#include “afxsocket.h”
3 添加CCoseDlg 添加成员函数
BOOL InitSocket()
{
m_socket = socket(AF_INET,SOCK_DGRAM,0);
if(INVALID_SOCKET == m_socket)
{
MessageBox("创建套接字失败!");
return false;
}
}BOOLCChatDlg::InitSocket()
{
//创建套接字
m_socket = socket(AF_INET,SOCK_DGRAM,0);
if(INVALID_SOCKET == m_socket)
{
MessageBox("创建套接字失败!");
return false;
}
//绑定
SOCKADDR_IN addrSock;
addrSock.sin_addr.S_un.S_addr =htonl(INADDR_ANY);
addrSock.sin_family = AF_INET;
addrSock.sin_port = htons(6000);
int Bind;
Bind =bind(m_socket,(SOCKADDR*)&addrSock,sizeof(sockaddr));
if(SOCKET_ERROR == Bind)
{
closesocket(m_socket);
MessageBox("bind error !");
return false;
}
return true;
}
3CCoseDlg 的OnInitDialog()中调用InitSocket()函数,初始化对话框,创建套接字,绑定套接字
//调用InitSocket()创建套接字,初始化套接字,绑定套接字
InitSocket();
4 在CCoseDlg.h类外部定义一个结构体
structRECVPARAM
{
SOCKET sock;
HWND hwnd;
};
5 在CCoseDlg.cpp的OnInitDialog()中添加线程代码