http://blog.sina.com.cn/s/blog_69c961b70100l260.html
在软件开发中“网络编程”是必不可少的基本功了;本文所讲的Socket编程也就是网络编程中的一种形式;当然你如果想问我什么叫“Socket”,很遗憾的是我也不能准确的告诉你!但我们可以确定的是Sock并不是一种网络协议,它只是一个网络编程接口,也就是说,它不是协议,但是它可以访问很多种网络协议,你可以把他当作一些协议的封装。
Socket编程涉及Socket服务端与客户端编程;与VC6下的Socket编程一样(VC6用ws2_32.lib库,而WinCE则用Ws2.lib库),服务端与客户端编程都需经历如下步骤:
服务端步骤:
1:加载套接字库,创建套接字(WSAStartup()/socket());
2:绑定套接字到一个IP地址和一个端口上(bind());
3:将套接字设置为监听模式等待连接请求(listen());
4:请求到来后,接受连接请求,返回一个新的对应于此次连接的套接字(accept());
5:用返回的套接字和客户端进行通信(send()/recv());
6:返回,等待另一连接请求;
7:关闭套接字,关闭加载的套接字库(closesocket()/WSACleanup())。
客户端步骤:
1:加载套接字库,创建套接字(WSAStartup()/socket());
2:向服务器发出连接请求(connect());
3:和服务器端进行通信(send()/recv());
4:关闭套接字,关闭加载的套接字库(closesocket()/WSACleanup())。
简单服务端例子如下:
#include <Winsock2.h>
#pragma comment( lib, "Ws2.lib" )
void TestSocketServer( void )
{
WSADATA wsaData;
if (WSAStartup(0x0202, &wsaData)!=0)
{
return;
}
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[50];
sprintf(sendBuf,"Welcome %s to here!",inet_ntoa(addrClient.sin_addr));
send(sockConn,sendBuf,strlen(sendBuf)+1,0);
char recvBuf[50];
recv(sockConn,recvBuf,50,0);
closesocket(sockConn);
}
}
简单客户端例子如下:
#include <Winsock2.h>
#pragma comment( lib, "Ws2.lib" )
void TestSocketClient( void )
{
WSADATA wsaData;
if (WSAStartup(0x0202, &wsaData)!=0)
{
return;
}
SOCKET sockClient=socket(AF_INET,SOCK_STREAM,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);
connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
send(sockClient,"hello",strlen("hello")+1,0);
char recvBuf[50];
recv(sockClient,recvBuf,50,0);
closesocket(sockClient);
WSACleanup();
}
上面我们简单的讲述了WinCE下Socket编程的相关步骤与实现例子,当然在实际的应用中光靠这个些是远够的,因为还有更的东西需要我们去处理(比如出错了怎么办?怎么设置相关超时等);下面我本人写的一个简单TCP客户端类,本类适应与WinCE、WinMobile、PocketPC等平台;至于本类的使用方法请台见本文对应例子代码;本类所在头文件内容如下:
//STCPClient.h
#ifndef SIMPLE_TCP_CLIENT_H
#define SIMPLE_TCP_CLIENT_H
#include <Winsock2.h>
#define TCPCLIENT_STATUS_NOTINIT 0
#define TCPCLIENT_STATUS_INITED 1
#define TCPCLIENT_STATUS_CONNECTED 2
#define TCPCLIENT_STATUS_CLOSED 3
typedef struct {
u_long onoff;
u_long keepalivetime;
u_long keepaliveinterval;
}TCP_KPALIVE,*PTCP_KEEPALIVE;
class CSTCPClient
{
public:
CSTCPClient( );
virtual ~CSTCPClient( );
public:
//设置服务端IP
int SetServerIP( const char* pIp );
//设置服务端端口
int SetServerPort( int nPort );
//设置接收缓冲区大小
int SetRecvBufferSize( int nSize );
//设置发送缓冲区大小
int SetSendBufferSize( int nSize );
//设置读数据超时(CE下不可用)
int SetOnceReadTimeOut( long lTimeOut );
//设置写数据超时(CE下不可用)
int SetOnceWriteTimeOut( long lTimeOut );
//获取服务端IP
char* GetServerIP( void );
//获取服务端端口
int GetServerPort( );
//获取接收缓冲区大小
int GetRecvBufferSize( void );
//获取发送缓冲区大小
int GetSendBufferSize( void );
//获取读数据超时
long GetOnceReadTimeOut( void );
//获取写数据超时
long GetOnceWriteTimeOut( void );
//初始化Socket环境
int Init( void );
//释放Socket环境
int Release( void );
//连接服务器
int Open( void );
//测试并连接服务器(服务器需相关协议支持)
int TestAndOpen( void );
//断开连接
int Close( void );
//读数据
int Read( char* sBuf, int nLen, int& nErrCode, long lTimeOut );
//发送数据
int Write( const char* sBuf, int nLen, int& nErrCode, long lTimeOut );
public:
//获取当前是否有数据可读状态
int ReadStatus( );
//获取当前是否可向服务器发送数据状态
int WriteStatus( );
//获取当前连接状态
int Status( );
private:
int SetSockKeepAvtiveTime( );
private:
int m_nCurStatus;
char m_sServerIP[30];
int m_nServerPort;
int m_nRecvBufferSize;
int m_nSendBufferSize;
long m_lOnceReadTimeOut;
long m_lOnceWriteTimeOut;
SOCKET m_ConnectSocket;
TCP_KPALIVE m_tKeepAlive;
};
#endif