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

📄 pcrecv.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
字号:
/*
 *  Alternative socket receive handlers (see Waterloo manual)
 *
 */
#include <stdio.h>
#include <stdlib.h>

#include "wattcp.h"
#include "strings.h"
#include "language.h"
#include "pcbuf.h"
#include "pcrecv.h"


/*
 *  _recvdaemon - gets upcalled when data arrives
 */
static int _recvdaemon (udp_Socket *s, BYTE *data, int len,
                        tcp_PseudoHeader *ph, udp_Header *udp)
{
  recv_data *r;
  recv_buf  *p;
  int i;

  switch (s->ip_type)
  {
    case UDP_PROTO:
         r = (recv_data*)s->rdata;
         p = (recv_buf*) r->recv_bufs;
         if (r->recv_sig != RECV_USED)
         {
           outsnl (_LANG("ERROR: udp recv data conflict"));
           return (0);
         }
         /* find an unused buffer
          */
         for (i = 0; i < r->recv_bufnum; i++, p++)
             switch (p->buf_sig)
             {
               case RECV_USED:
                    break;
               case RECV_UNUSED:  /* take this one */
                    p->buf_sig     = RECV_USED;
                    p->buf_hisip   = ph->src;
                    p->buf_hisport = udp->srcPort;
                    len = min (len, sizeof(p->buf_data));
                    if (len > 0)
                    {
                      memcpy (p->buf_data, data, len);
                      p->buf_len = len;
                    }
                    else
                      p->buf_len = -1;  /* a 0-byte probe */
                    return (0);
               default:
                    outsnl (_LANG("ERROR: sock_recv_daemon data err"));
                    return (0);
             }
         return (0);

#if !defined(USE_UDP_ONLY)
    case TCP_PROTO:
         {
           tcp_Socket *t = (tcp_Socket*) s;

           r = (recv_data*) t->rdata;
           if (len > t->max_seg)
              return (0);

           if (r->recv_sig != RECV_USED)
           {
             outsnl (_LANG("ERROR: tcp recv data conflict"));
             return (0);
           }
           /* stick it on the end if you can
            */
           i = t->maxrdatalen - t->rdatalen;
           if (i > 1)
           {
             /* we can accept some of this */
             if (len > i)
                 len = i;
             if (len > 0)
                memcpy (&r->recv_bufs[s->rdatalen], data, len);
             s->rdatalen += len;
             return (len);
           }
           return (0);   /* didn't take none */
         }
#endif
  }
  return (0);
}


int sock_recv_used (udp_Socket *s)
{
  recv_data  *r;
  recv_buf   *p;

  int i, len;

  switch (_chk_socket((sock_type*)s))
  {
    case VALID_UDP:
         r = (recv_data*)s->rdata;
         p = (recv_buf*) r->recv_bufs;
         if (r->recv_sig != RECV_USED)
            return (-1);

         for (i = len = 0; i < r->recv_bufnum; i++, p++)
             if (p->buf_sig == RECV_USED)
                len += abs (p->buf_len);
         return (len);

#if !defined(USE_UDP_ONLY)
    case VALID_TCP:
         {
           tcp_Socket *t = (tcp_Socket*)s;

           r = (recv_data*) t->rdata;
           if (r->recv_sig != RECV_USED)
              return (-1);
           return (t->rdatalen);
         }
#endif
  }
  return (0);
}


int sock_recv_init (udp_Socket *s, void *space, int len)
{
  recv_buf  *p = space;
  recv_data *r = (recv_data*) &s->rddata[0];
  int i;

  memset (p, 0, len);                /* clear data area */
  memset (r, 0, sizeof(s->rddata));  /* clear table */

  s->protoHandler = (ProtoHandler) _recvdaemon;
  r->recv_sig     = RECV_USED;
  r->recv_bufs    = (BYTE*) p;
  r->recv_bufnum  = len / sizeof(recv_buf);
  if (s->ip_type == UDP_PROTO)
     for (i = 0; i < r->recv_bufnum; i++, p++)
         p->buf_sig = RECV_UNUSED;
  return (0);
}

#if defined(USE_BSD_FUNC)

int sock_recv_from (udp_Socket *s, DWORD *hisip, WORD *hisport,
                    char *buffer, int len, int peek)
{
  tcp_Socket *t;
  recv_buf   *p;
  recv_data  *r = (recv_data*) s->rdata;
  int i;

  if (r->recv_sig != RECV_USED)
     return (-1);

  switch (s->ip_type)
  {
    case UDP_PROTO:
         p = (recv_buf*) r->recv_bufs;

         /* find a used buffer
          */
         for (i = 0; i < r->recv_bufnum; i++, p++)
         {
           switch (p->buf_sig)
           {
             case RECV_UNUSED:
                  break;
             case RECV_USED:
                  if (p->buf_len < 0)  /* a 0-byte probe packet */
                     len = -1;
                  else
                  {
                    len = min (p->buf_len, len);
                    memcpy (buffer, p->buf_data, len);
                  }
                  if (hisip)
                     *hisip = p->buf_hisip;
                  if (hisport)
                     *hisport = p->buf_hisport;
                  if (!peek)
                     p->buf_sig = RECV_UNUSED;
                  return (len);
             default:
                  outsnl (_LANG("ERROR: sock_recv_init data err"));
                  return (0);
           }
         }
         return (0);

#if !defined(USE_UDP_ONLY)
    case TCP_PROTO:
         t = (tcp_Socket*) s;
         if (len > t->rdatalen)
             len = t->rdatalen;
         if (len)
             memcpy (buffer, r->recv_bufs, len);
         return (len);
#endif
  }
  return (0);
}
#endif  /* USE_BSD_FUNC */


int sock_recv (udp_Socket *s, char *buffer, int len)
{
  recv_buf   *p;
  recv_data  *r = (recv_data*) s->rdata;
  int i;

  if (r->recv_sig != RECV_USED)
     return (-1);

  switch (s->ip_type)
  {
    case UDP_PROTO:
         p = (recv_buf*) r->recv_bufs;

         /* find a used buffer
          */
         for (i = 0; i < r->recv_bufnum; i++, p++)
         {
           switch (p->buf_sig)
           {
             case RECV_UNUSED:
                  break;
             case RECV_USED:
                  if (len > p->buf_len)
                      len = p->buf_len;
                  if (len > 0)
                     memcpy (buffer, p->buf_data, len);
                  p->buf_sig = RECV_UNUSED;
                  return (len);
             default:
                  outsnl (_LANG("ERROR: sock_recv_init data err"));
                  return (0);
           }
         }
         return (0);

#if !defined(USE_UDP_ONLY)
    case TCP_PROTO :
         {
           tcp_Socket *t = (tcp_Socket*) s;

           if (len > t->rdatalen)
               len = t->rdatalen;
           if (len)
              memcpy (buffer, r->recv_bufs, len);
           return (len);
         }
#endif
  }
  return (0);
}

⌨️ 快捷键说明

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