⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 server.c

📁 Open DMT Client C Source code
💻 C
字号:
// ----------------------------------------------------------------------------// Copyright 2006-2007, Martin D. Flynn// All rights reserved// ----------------------------------------------------------------------------//// Licensed under the Apache License, Version 2.0 (the "License");// you may not use this file except in compliance with the License.// You may obtain a copy of the License at// // http://www.apache.org/licenses/LICENSE-2.0// // Unless required by applicable law or agreed to in writing, software// distributed under the License is distributed on an "AS IS" BASIS,// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.// See the License for the specific language governing permissions and// limitations under the License.//// ----------------------------------------------------------------------------// Description://  Server transport support for socket DMTP communications.// ---// Change History://  2006/01/04  Martin D. Flynn//     -Initial release//  2006/01/27  Martin D. Flynn//     -Set default port to 31000// ----------------------------------------------------------------------------#include <stdlib.h>#include <stdio.h>#include <string.h>#include <ctype.h>#include <sys/types.h>#include <sys/stat.h>#include <unistd.h>#include "tools/stdtypes.h"#include "tools/strtools.h"#include "tools/base64.h"#include "tools/checksum.h"#include "tools/sockets.h"#include "server/defaults.h"#include "server/server.h"#include "server/serrors.h"#include "server/packet.h"#include "server/protocol.h"#include "server/log.h"// ----------------------------------------------------------------------------#define DEFAULT_SERVER_PORT     31000 // this default may change at any timestatic Socket_t         serverSocket;static PacketEncoding_t clientPacketEncoding = ENCODING_HEX;// ----------------------------------------------------------------------------void serverInitialize(){        /* init server port */    socketInitStruct(&serverSocket, (char*)0, 0, SOCK_STREAM);    }// ----------------------------------------------------------------------------utBool serverIsOpen(){    return socketIsOpenClient(&serverSocket);}utBool serverOpen(const char *portName, utBool portLog){    logINFO(LOGSRC,"Waiting for client socket ...");    int sockPort = (int)strParseInt32(portName, (Int32)DEFAULT_SERVER_PORT);    /* close, if already open */    if (serverIsOpen()) {        // it shouldn't already be open        logWARNING(LOGSRC,"Server port seems to still be open!");        serverClose();    }        /* open server port */    if (!socketIsOpenServer(&serverSocket)) {        if (sockPort < 0) {            logWARNING(LOGSRC,"Invalid socket port: %d", sockPort);            return utFalse;        }        int err = socketOpenTCPServer(&serverSocket, sockPort);        if (err < 0) {            logWARNING(LOGSRC,"Unable to open server socket: %d", sockPort);            return utFalse;        }    }        /* wait for incoming client */    if (socketAcceptTCPClient(&serverSocket) < 0) {        logWARNING(LOGSRC,"Unable to accept client socket");        return utFalse;    }    /* return successful */    return utTrue;    }utBool serverClose(){    if (serverIsOpen()) {        socketCloseClient(&serverSocket);        //socketCloseServer(&serverSocket);        return utTrue;    } else {        return utFalse;    }}// ----------------------------------------------------------------------------/* flush input buffer */void serverReadFlush(){    // flush (not necessary)}// ----------------------------------------------------------------------------static int _serverRead(UInt8 *buf, int bufLen){        /* no data was requested */    if (bufLen == 0) {        logERROR(LOGSRC,"NULL buffer");        return 0;    }        /* port open? */    if (!serverIsOpen()) {        logERROR(LOGSRC,"Server port not open!!!");        return -1;    }        /* return bytes read */    int readLen = 0;    readLen = socketReadTCP(&serverSocket, buf, bufLen, 3000L);    return readLen;    }static int _serverReadPacketBuffer(UInt8 *buf, int bufLen){    UInt8 *b = buf;    int readLen = 0, len;        /* read header */    // This will read the header/type/length of a binary encoded packet, or    // the '$' and 2 ASCII hex digits of an ASCII encoded packet.    len = _serverRead(b, PACKET_HEADER_LENGTH);    if (len < 0) {        logERROR(LOGSRC,"Read error (packet header)");        return SRVERR_TRANSPORT_ERROR;    } else    if (len == 0) {        //logERROR(LOGSRC,"Timeout (packet header)");        return SRVERR_TIMEOUT;    }    /* make sure entire header has been read */    if (len < PACKET_HEADER_LENGTH) {        // partial packet read (just close socket)        logERROR(LOGSRC,"Read error [len=%d, expected %d]", len, PACKET_HEADER_LENGTH);        return SRVERR_TRANSPORT_ERROR;    }    b += PACKET_HEADER_LENGTH;        /* read payload */    if (buf[0] == PACKET_ASCII_ENCODING_CHAR) {        // ASCII encoded, read until '\r'        for (; (b - buf) < bufLen; b++) {            len = _serverRead(b, 1);            if (len < 0) {                logERROR(LOGSRC,"Read error");                return SRVERR_TRANSPORT_ERROR;            } else            if (len == 0) {                // timeout (partial packet read)                logERROR(LOGSRC,"Timeoout");                return SRVERR_TIMEOUT;            }            if (*b == PACKET_ASCII_ENCODING_EOL) {                *b = 0;                break;            }        }        if ((b - buf) < bufLen) {            readLen = (b - buf);        } else {            // overflow (just close socket) - unlikely            logERROR(LOGSRC,"Read overflow");            return SRVERR_PACKET_LENGTH;        }    } else    if (buf[PACKET_HEADER_LENGTH - 1] != 0) {        // read 'b[2]' bytes        UInt16 payloadLen = (UInt16)buf[PACKET_HEADER_LENGTH - 1];        len = _serverRead(b, payloadLen);        if (len < 0) {            logERROR(LOGSRC,"Read error");            return SRVERR_TRANSPORT_ERROR;        }        if (len < payloadLen) {            // timeout / transport-error (partial packet read)            logERROR(LOGSRC,"Timeout (expected=%d, read=%d)", payloadLen, len);            return SRVERR_TRANSPORT_ERROR;        }        readLen = PACKET_HEADER_LENGTH + len;    } else {        readLen = PACKET_HEADER_LENGTH;    }        /* return length */    return SRVERR_OK;    }static int _serverParsePacket(Packet_t *pkt, const UInt8 *pktBuf){        /* clear packet */    memset(pkt, 0, sizeof(Packet_t));        /* parse header/data */    if (*pktBuf == PACKET_ASCII_ENCODING_CHAR) {        // The packet is assumed to be null-terminated (ie. '\r' was replaced with '0')                /* print packet */        //logINFO(LOGSRC,"==> %2d] %s\n", strlen(pktBuf), pktBuf);                 /* parse */        int pktBufLen;        if (!cksumIsValidCharXOR(pktBuf, &pktBufLen)) {            // checksum failed: ERROR_PACKET_CHECKSUM            logERROR(LOGSRC,"Invalid packet checksum");            serverWriteError("%2x%2x", (UInt32)NAK_PACKET_CHECKSUM, (UInt32)0);            return SRVERR_CHECKSUM_FAILED;        } else        if (pktBufLen < 5) {            // invalid length: ERROR_PACKET_LENGTH            logERROR(LOGSRC,"Invalid packet length");            serverWriteError("%2x%2x", (UInt32)NAK_PACKET_LENGTH, (UInt32)0);            return SRVERR_PARSE_ERROR;        } else {            UInt8 buf[2];            int hlen = strParseHex(pktBuf + 1, 4, buf, sizeof(buf));            if (hlen != 2) {                // header was not parsable: ERROR_PACKET_HEADER                logERROR(LOGSRC,"Header not parsable");                serverWriteError("%2x%2x", (UInt32)NAK_PACKET_HEADER, (UInt32)0);                return SRVERR_PARSE_ERROR;            } else {                pkt->hdrType = CLIENT_HEADER_TYPE(buf[0],buf[1]);                logERROR(LOGSRC,"Header %04X", pkt->hdrType);                if (pktBufLen > 6) { // $E0FF:XXXX...                    // encoded character, plus data                    if (pktBuf[5] == ENCODING_BASE64_CHAR) {                        int len = (UInt8)base64Decode(pktBuf + 6, pktBufLen - 6, pkt->data, sizeof(pkt->data));                        pkt->dataLen = (len >= 0)? (UInt8)len : 0;                    } else                    if (pktBuf[5] == ENCODING_HEX_CHAR) {                        int len = (UInt8)strParseHex(pktBuf + 6, pktBufLen - 6, pkt->data, sizeof(pkt->data));                        pkt->dataLen = (len >= 0)? (UInt8)len : 0;                    } else                    if (pktBuf[5] == ENCODING_CSV_CHAR) {                        // unsupported encoding: ERROR_PACKET_ENCODING                        // parsing CSV encoded packets is not supported in this implementation                        logWARNING(LOGSRC,"CSV parsing is not supported.\n");                        serverWriteError("%2x%2x", (UInt32)NAK_PACKET_ENCODING, (UInt32)pkt->hdrType);                        return SRVERR_PARSE_ERROR;                    } else {                        // unrecognized encoding: ERROR_PACKET_ENCODING                        serverWriteError("%2x%2x", (UInt32)NAK_PACKET_ENCODING, (UInt32)pkt->hdrType);                        return SRVERR_PARSE_ERROR;                    }                }            }        }            } else    if (*pktBuf == PACKET_HEADER_BASIC) {        // The packet header is assumed to be a valid length.                /* print packet */        //UInt8 hex[PACKET_MAX_ENCODED_LENGTH];        //UInt16 len = (UInt16)pktBuf[2] + 3;        //logINFO(LOGSRC,"==> %2d] 0x%s\n", len, strEncodeHex(hex, sizeof(hex), pktBuf, len));                 /* parse into packet */        pkt->hdrType = CLIENT_HEADER_TYPE(pktBuf[0],pktBuf[1]);        //logINFO(LOGSRC,"Header %04X", pkt->hdrType);        pkt->dataLen = (UInt8)pktBuf[2];        if (pkt->dataLen > 0) {            memcpy(pkt->data, pktBuf + 3, (int)pkt->dataLen);        }            } else {                // invalid header: ERROR_PACKET_HEADER        logERROR(LOGSRC,"Invalid packet header");        ClientPacketType_t hdrType = CLIENT_HEADER_TYPE(pktBuf[0],pktBuf[1]);        serverWriteError("%2x%2x", (UInt32)NAK_PACKET_HEADER, (UInt32)hdrType);        return SRVERR_PARSE_ERROR;            }        /* return packet */    return SRVERR_OK;}int serverReadPacket(Packet_t *pkt){    UInt8 buf[600];        /* read client packet */    int err = _serverReadPacketBuffer(buf, sizeof(buf));    if (err != SRVERR_OK) {        // timeout/error        return err;    }        /* parse packet */    err = _serverParsePacket(pkt, buf);    //logINFO(LOGSRC,"Client Packet HEADER=%04X", pkt->hdrType);    return err;}// ----------------------------------------------------------------------------static int _serverWrite(const UInt8 *buf, int bufLen){        /* nothing specified to write */    if (bufLen == 0) {        return 0;    }    /* write packet */    int len = 0;    len = socketWriteTCP(&serverSocket, buf, bufLen);    return len;    }utBool serverWritePacket(Packet_t *pkt){    UInt8 buf[PACKET_MAX_ENCODED_LENGTH];    Buffer_t bb, *dest = binBuffer(&bb, buf, sizeof(buf), BUFFER_DESTINATION);    int len = pktEncodePacket(dest, pkt, clientPacketEncoding);    if (len > 0) {        if (*buf == PACKET_ASCII_ENCODING_CHAR) {            logINFO(LOGSRC,"[TX] %.*s", len - 1, buf);         } else {            UInt8 hex[PACKET_MAX_ENCODED_LENGTH];            logINFO(LOGSRC,"[TX] 0x%s", strEncodeHex(hex, sizeof(hex), buf, len));         }        int wrtLen = _serverWrite(buf, len);        if (wrtLen == len) {            return utTrue;        } else {            return utFalse;        }    } else {        logWARNING(LOGSRC,"Invalid packet\n");        return utFalse;    }}utBool serverWritePacketFmt(ServerPacketType_t pktType, const char *fmt, ...){    Packet_t pkt;    va_list ap;    va_start(ap, fmt);    pktVInit(&pkt, pktType, fmt, ap);    va_end(ap);    return serverWritePacket(&pkt);}utBool serverWriteError(const char *fmt, ...){    Packet_t pkt;    va_list ap;    va_start(ap, fmt);    pktVInit(&pkt, PKT_SERVER_ERROR, fmt, ap);    va_end(ap);    return serverWritePacket(&pkt);}// ----------------------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -