📄 sgip_function.cpp
字号:
#include "sgip_function.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////////////////
//Winsock封装
/*
创建端口
*/
int sgip_create_tcp_socket(SOCKET &hSocket)
{
if ( (hSocket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP )) == INVALID_SOCKET )
{
return SGIP_SOCKET_CREATEFAIL;
}
return SGIP_SUCCESS;
}
/*
关闭端口
*/
int sgip_socket_close(SOCKET& hSocket)
{
if ( closesocket( hSocket ) == SOCKET_ERROR )
{
return SGIP_CLOSESOCKET_ERROR;
}
memset( &hSocket, 0, sizeof( sockaddr_in ) );
memset( &hSocket, 0, sizeof( sockaddr_in ) );
return SGIP_SUCCESS;
}
/*
捆绑端口
*/
int sgip_socket_bind(SOCKET hSocket, int nPort)
{
//if( strlen( strIP ) == 0 || nPort == 0 )
// return ERR_BADPARAM;
struct sockaddr_in sockaddr;
memset( &sockaddr,0, sizeof( sockaddr ) );
sockaddr.sin_family = AF_INET;
sockaddr.sin_addr.s_addr = inet_addr( "127.0.0.1" );
sockaddr.sin_port = htons( nPort );
if ( bind( hSocket, (SOCKADDR*)&sockaddr, sizeof( sockaddr ) ) == SOCKET_ERROR )
{
return SGIP_SOCKET_BINDFAIL; //暂定
}
return SGIP_SUCCESS;
}
/*
accept
hServer 监听socket
hClient 接入的套接字,
rsockaddr 连接来的远程端口的信息被填入
*/
int sgip_socket_accept(SOCKET hServer, SOCKET &hClient)
{
struct sockaddr_in rsockaddr;
int Len = sizeof( rsockaddr );
memset( &rsockaddr, 0, sizeof( rsockaddr ) );
if( ( hClient = accept( hServer, (SOCKADDR*)&rsockaddr, &Len ) ) == INVALID_SOCKET )
{
return SGIP_SOCKET_ACCEPTFAIL;
}
return SGIP_SUCCESS;
}
/*
sServAddr 远程端口信息,这里作为ip 地址处理,
*/
int sgip_socket_connect(SOCKET hSocket, const char *sServAddr, int nPort)
{
if (sServAddr == NULL || nPort == 0)
{
return SGIP_SOCKET_INVALPARAM;
}
struct sockaddr_in rsockaddr;
rsockaddr.sin_family = AF_INET;
rsockaddr.sin_addr.s_addr = inet_addr(sServAddr);
rsockaddr.sin_port = htons(nPort);
if( connect( hSocket, (SOCKADDR*)&rsockaddr, sizeof( rsockaddr ) ) == SOCKET_ERROR )
{
return SGIP_SOCKET_CONNECTFAIL;
}
return SGIP_SUCCESS;
}
/*
采用的是非阻塞模式下的的send
是否要切换到非阻塞模式下运行?
*/
int sgip_socket_select_send(SOCKET hSocket, const char *sBuffer, int nSize, int nTimeOut)
{
fd_set fds;
int n;
struct timeval tv;
// set up the file descriptor set
FD_ZERO(&fds);
FD_SET(hSocket, &fds);
tv.tv_sec = nTimeOut;
tv.tv_usec = 0;
// wait until timeout or data received
n = select(hSocket + 1, &fds, NULL, NULL, &tv);
if (n == 0)
return SGIP_SOCKET_SENDTIMEOUT; //timeout
if (n == -1)
return SGIP_SOCKET_SENDERROR; // error
// data must be here, so do a normal recv()
if ( send(hSocket, sBuffer, nSize, 0) == SOCKET_ERROR )
return SGIP_SOCKET_RECVERROR;
return SGIP_SUCCESS;
}
/*
接受时超时处理
*/
int sgip_socket_select_recv(SOCKET hSocket, char *sBuffer, int nSize, int nTimeOut)
{
fd_set fds;
int n;
struct timeval tv;
// set up the file descriptor set
FD_ZERO(&fds);
FD_SET(hSocket, &fds);
tv.tv_sec = nTimeOut;
tv.tv_usec = 0;
// wait until timeout or data received
n = select(hSocket + 1, &fds, NULL, NULL, &tv);
if (n == 0)
return SGIP_SOCKET_RECVTIMEOUT; //timeout
if (n == -1)
return SGIP_SOCKET_RECVERROR; // error
if (recv(hSocket, sBuffer, nSize, 0) == SOCKET_ERROR)
return SGIP_SOCKET_RECVERROR;
return SGIP_SUCCESS;
}
/*
发送成功
success 返回SGIP_SUCCESS
error 返回对应的错误码
*/
int sgip_socket_send(SOCKET hSocket, const char *sBuffer, int nSize)
{
if( sBuffer == NULL || nSize == 0 )
return SGIP_API_INVALPARAM;
int iRet = send(hSocket ,sBuffer, nSize, 0);
if( send(hSocket, sBuffer, nSize, 0 ) == SOCKET_ERROR )
{
return SGIP_SOCKET_SENDERROR;
}
return SGIP_SUCCESS;
}
/*
阻塞模式下的接受
*/
int sgip_socket_recv(SOCKET hSocket, char *sBuffer, int nSize)
{
if (sBuffer == NULL || nSize == 0)
return SGIP_API_INVALPARAM;
int len = 0;
int ret = 0;
ret = recv( hSocket, sBuffer, nSize, 0 );
if ( ret == SOCKET_ERROR )
{
return SGIP_SOCKET_RECVERROR;
}
return SGIP_SUCCESS;
}
/////////////////////////////////////////////////////////////////////////////////////////
//协议实现
/*
sp 连接网关
sSrvAddr 服务地址
nPort 端口
*/
int sgip_connect_to_ismg(const char *sSrvAddr, int nPort, sgip_conn *conn)
{
if (sgip_create_tcp_socket(conn->hSocket) != SGIP_SUCCESS)
{
return -1;
}
if (sgip_socket_connect(conn->hSocket, sSrvAddr,nPort) != SGIP_SUCCESS)
{
return -1;
}
conn->remotePort = nPort;
return 0;
}
/*
网关smg 断开和sp连接,需要关闭和smg连接的端口
sp主动断开连接,需要发送bind包
sp被动断开连接,则直接close
*/
int sgip_disconnect_from_ismg(sgip_conn *conn)
{
if (conn->hSocket == NULL)
{
return -1;
}
//需要先unbind才行
if (conn->fBinded)
{
return -1;
}
return sgip_socket_close(conn->hSocket);
}
/*
sp连接网关,发送bind包
sc 包括用户名+密码
*/
int sgip_login(sgip_conn* conn, sgipg_connect *sc, const char* sSrcNum, unsigned int nSeq)
{
sgipg_head sthead; //包头信息
int nSize = SGIP_HEADLEN + SGIP_LOGINLEN;
sthead.nTotalLength = nSize;
sthead.nCommandId = SGIP_BIND;
sthead.nSequenceId.nSrcNodeNum = conn->nSrcNum; // 源节点编号
sthead.nSequenceId.nDateTime = sgip_get_datetime();
sthead.nSequenceId.nSeqId = nSeq; // 序列号
char *sBuffer = new char[nSize];
memcpy(sBuffer, &sthead, SGIP_HEADLEN);
memcpy(sBuffer + SGIP_HEADLEN, sc, SGIP_LOGINLEN);
int iRet;
iRet = sgip_socket_send(conn->hSocket, sBuffer, nSize);
if (iRet != 0)
{
return -1;
}
int nTimeOut = 100;
sgipg_packet sp;
//login reponse 返回
iRet = sgip_recv(conn, &sp, nTimeOut);
if (iRet != 0)
{
return -1;
}
return 0;
}
/*
login 参数设置
*/
int sgip_login_value_set(sgipg_connect *sc, int nLoginType, const char *sLoginName, const char *sLoginPwd)
{
sprintf((char*)sc->cLoginType, "%d", nLoginType);
strcpy(sc->sLoginName , sLoginName);
strcpy(sc->sLoginPwd, sLoginPwd);
return 0;
}
/*
unbind
需要改写conn中的值
*/
int sgip_logout(sgip_conn* conn, unsigned int nSeq)
{
sgipg_head sthead; //包头信息
int nSize = SGIP_HEADLEN;
sthead.nTotalLength = nSize; // 消息总长度(包括消息头)
sthead.nCommandId = SGIP_UNBIND; // 命令字
sthead.nSequenceId.nSrcNodeNum = conn->nSrcNum; // 源节点编号
sthead.nSequenceId.nDateTime = sgip_get_datetime();//nDateTime; // 日期时间,如:1120203225
sthead.nSequenceId.nSeqId = nSeq; // 序列号
char *sBuffer = new char[nSize];
memcpy(sBuffer, &sthead, SGIP_HEADLEN);
int iRet;
iRet = sgip_socket_send(conn->hSocket, sBuffer, nSize);
//不管收到与否都要断开连接
return 0;
}
/******************************************************
下行处理,其中conn为当前连接的网关socket,
应该包括处理完以后的recv
*/
int sgip_submit(sgip_conn* conn, sgipg_submit* ss, unsigned int nSeq, unsigned int nDateTime)
{
sgipg_head sthead; //包头信息
int nSize = SGIP_SUBMITLEN + SGIP_HEADLEN;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -