1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
/*
* Portable network messaging routines.
* $Id$
* Copyright (c) 1997 by Tycho Softworks.
* For conditions of distribution and reuse see product license.
*/
#include <net/msgport.h>
#include <std/time.h>
static ushort sequence = 0;
SOCKET create_msgport(char *mask, int port, int backlog)
{
if(backlog)
return tcpsocket(mask, port, backlog);
else
return udpsocket(mask, port);
}
size_t send_msgport(SOCKET so, SOCKMSG *buf, size_t len, bool flag)
{
size_t stat;
memset(buf, 0, sizeof(SOCKMSG));
if(flag)
++sequence;
buf->header.len = htonl(len);
buf->sequence = sequence;
stat = send(so, buf, len + sizeof(SOCKMSG), 0);
if (stat > 0)
return stat - sizeof(SOCKMSG);
return stat;
}
size_t recv_msgport(SOCKET so, SOCKMSG *buf, size_t len, bool any)
{
int alen;
size_t mlen;
size_t stat;
SOCKMSG saddr;
for(;;)
{
alen = recv(so, &saddr, sizeof(saddr), MSG_PEEK);
if(alen < 0)
return stat;
mlen = ntohl(saddr.header.len);
if (mlen > len)
mlen = len;
stat = recvfrom(so, buf, mlen + sizeof(saddr), 0, (struct sockaddr *)&saddr, &alen);
memcpy(buf, &saddr, alen);
if (stat > 0)
{
if(any && buf->sequence != sequence)
continue;
return stat - sizeof(SOCKMSG);
}
return stat;
}
}
size_t reply_msgport(SOCKET so, SOCKMSG *buf, SOCKMSG *org, size_t len)
{
size_t stat;
SOCKMSG saddr;
if(!org)
org = buf;
memcpy(&saddr, org, sizeof(saddr));
buf->header.len = htonl(len);
stat = sendto(so, buf, len + sizeof(SOCKMSG), 0, (struct sockaddr *)&saddr, sizeof(saddr));
if (stat > 0)
return stat - sizeof(SOCKMSG);
return stat;
}
|