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

📄 dtcpsmpc.cpp

📁 Simple Module Procedure Call for windows & QNx
💻 CPP
字号:
#include <stdio.h>

#ifdef WIN32
 #include <windows.h>
 #include <winsock.h>
#else
 #include <string.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <netdb.h>
 #include <netinet/tcp.h>
 #include <process.h>

 typedef int        SOCKET;
 typedef hostent*        PHOSTENT;
 typedef sockaddr*        PSOCKADDR;
 typedef sockaddr*        LPSOCKADDR;
 typedef sockaddr_in        SOCKADDR_IN;

 #define closesocket        close

 #define SOCKET_ERROR        -1
 #define INVALID_SOCKET        -1

 typedef unsigned long        DWORD;
 typedef DWORD*        LPDWORD;
 typedef int (*        LPTHREAD_START_ROUTINE)(void*);
#endif

#include <smpc/dsmpccli.h>
#include "dsmpcmsg.h"

dword Send(SOCKET sock, void* buffer, dword size)
{
 for(dword i = 0, ii; i < size; i += ii)
  if((ii = send(sock,(char*)buffer + i,size - i,0)) == SOCKET_ERROR) break;
 return i;
}

dword Recv(SOCKET sock, void* buffer, dword size)
{
 for(dword i = 0, ii; i < size; i += ii)
  if((ii = recv(sock,(char*)buffer + i,size - i,0)) == 0 || ii == SOCKET_ERROR) break;
 return i;
}

class DUniTypeClient : public DSmpcClient
{
 private:
  dword type;

 public:
  DUniTypeClient(DSmpc* smpc, dword sid, dword _type)
  : DSmpcClient(smpc,sid,_type) { type = _type; }

  virtual dword Type(void) const { return type; }
};

class DSmpcBuffer
{
 private:
  char* buffer;
  dword size;

 public:
  DSmpcBuffer(void) { buffer = 0; size = 0; }

  dword Size(dword send, dword recv = 0)
  {
   dword nsize = send > recv ? send : recv;
   if(nsize > size || nsize < (size >> 1)) {
    if(buffer) delete buffer;
    size = nsize;
    buffer = size ? new char[size] : 0;
    if(!buffer && send && send < recv)
     buffer = new char[size];
    if(!buffer) size = 0;
   }
   return size;
  }

  dword Size(void) const { return size; }

  char* Buffer(void) { return buffer; }
};

dword normal_size = 0;

DWORD TcpServer(LPDWORD psock)
{
 SOCKET sock = *psock;
 DSmpcMsg msg, rmsg;
 DSmpcBuffer b;
 DSmpc* smpc = CreateSmpc();
 if(!smpc) { closesocket(sock); return 0; }

 while(1)
 {
  // Receive message header
  if(Recv(sock,&msg,sizeof(msg)) != sizeof(msg)) break;
  if(msg.msg != Smpc_Msg_Call) break;
  // Realloc buffer
  if(!b.Size(msg.send,msg.recv) && msg.send) break;
  // Receive message data
  if(Recv(sock,b.Buffer(),msg.send) != msg.send) break;

  // Call service
  if(b.Size() < msg.recv) msg.recv = b.Size();
  DUniTypeClient client(smpc,msg.sid,msg.type);
  DSmpcParam sp[] = {{b.Buffer(),msg.send}}, rp[] = {{b.Buffer(),msg.recv}};
  msg.error = client.Call(msg.proc,sp,1,rp,1);
  if(rp[0].size > msg.recv) msg.error = Smpc_Err_OutSize;
  msg.recv = msg.error == Smpc_Success ? rp[0].size : 0;
  msg.type = client.RemoteType();

  // Send message
  msg.msg = Smpc_Msg_Return;
  if(Send(sock,&msg,sizeof(msg)) != sizeof(msg)) break;
  if(Send(sock,b.Buffer(),msg.recv) != msg.recv) break;

  // Normalize buffer
  if(normal_size && b.Size() > normal_size) b.Size(normal_size);
 }

 delete smpc;
 closesocket(sock);
 return 0;
}

SOCKET s;

void TcpListen(SOCKET sock)
{
 SOCKADDR_IN sin;
 sin.sin_addr.s_addr = INADDR_ANY;
 sin.sin_port = htons(3001);
 sin.sin_family = AF_INET;

 if(bind(sock,(LPSOCKADDR)&sin,sizeof(sin)) == SOCKET_ERROR) return;
 if(listen(sock,5) == SOCKET_ERROR) return;

 for(int i = 0; (s = accept(sock,0,0)) != INVALID_SOCKET; i++)
 {
  int val = 1;
  setsockopt(s,getprotobyname("TCP")->p_proto,TCP_NODELAY,(const char*)&val,sizeof(val));
#ifdef MTHREAD
#ifdef WIN32
  DWORD tid = 0;
  if(!CreateThread(0,0,(LPTHREAD_START_ROUTINE)TcpServer,(LPDWORD)&s,0,&tid))
   closesocket(s);
#else
  char* stack = new char[10000];
  if(!stack || tfork(stack,10000,(LPTHREAD_START_ROUTINE)TcpServer,(LPDWORD)&s,0) == -1)
  { if(stack) delete stack; closesocket(s); }
#endif
#else
  TcpServer((LPDWORD)&s);
#endif
 }
}

void main(int argc, char* argv[])
{
 puts("TCP/IP to SMPC translator v1.00  Dynamics Co.Ltd  Copyright(C) - 1999");
 if(argc > 1) normal_size = atoi(argv[1]);

#ifdef WIN32
 WSADATA wsaData;
 if(WSAStartup(MAKEWORD(1,1),&wsaData)) return;
#endif

 SOCKET sock = socket(AF_INET,SOCK_STREAM,0);
 if(sock) {
  TcpListen(sock);
  perror("TcpListen");
  closesocket(sock);
 }

#ifdef WIN32
 WSACleanup();
#endif
}

⌨️ 快捷键说明

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