forked from data61/MP-SPDZ
-
Notifications
You must be signed in to change notification settings - Fork 0
/
sockets.h
144 lines (123 loc) · 2.91 KB
/
sockets.h
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#ifndef _sockets_h
#define _sockets_h
#include "Networking/data.h"
#include <errno.h> /* Errors */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/wait.h> /* Wait for Process Termination */
#include <iostream>
using namespace std;
void error(const char *str);
void set_up_client_socket(int& mysocket,const char* hostname,int Portnum);
void close_client_socket(int socket);
// send/receive integers
template<class T>
void send(T& socket, size_t a, size_t len);
template<class T>
void receive(T& socket, size_t& a, size_t len);
template<class T>
void send(T socket, octet* msg, size_t len);
template<class T>
void receive(T socket, octet* msg, size_t len);
inline size_t send_non_blocking(int socket, octet* msg, size_t len)
{
int j = send(socket,msg,len,MSG_DONTWAIT);
if (j < 0)
{
if (errno != EINTR and errno != EAGAIN and errno != EWOULDBLOCK)
{ error("Send error - 1 "); }
else
return 0;
}
return j;
}
template<>
inline void send(int socket,octet *msg,size_t len)
{
size_t i = 0;
while (i < len)
{
i += send_non_blocking(socket, msg + i, len - i);
}
}
template<class T>
inline void send(T& socket, size_t a, size_t len)
{
octet blen[len];
encode_length(blen, a, len);
send(socket, blen, len);
}
template<>
inline void receive(int socket,octet *msg,size_t len)
{
size_t i=0;
int fail = 0;
long wait = 1;
while (len-i>0)
{ int j=recv(socket,msg+i,len-i,0);
// success first
if (j > 0)
i = i + j;
else if (j < 0)
{
if (errno == EAGAIN or errno == EINTR)
{
if (++fail > 25)
error("Unavailable too many times");
else
{
usleep(wait *= 2);
}
}
else
{ error("Receiving error - 1"); }
}
else
throw closed_connection();
}
}
template<class T>
inline void receive(T& socket, size_t& a, size_t len)
{
octet blen[len];
receive(socket, blen, len);
a = decode_length(blen, len);
}
inline size_t check_non_blocking_result(int res)
{
if (res < 0)
{
if (errno != EWOULDBLOCK)
error("Non-blocking receiving error");
return 0;
}
return res;
}
inline size_t receive_non_blocking(int socket,octet *msg,int len)
{
int res = recv(socket, msg, len, MSG_DONTWAIT);
return check_non_blocking_result(res);
}
inline size_t receive_all_or_nothing(int socket,octet *msg,int len)
{
int res = recv(socket, msg, len, MSG_DONTWAIT | MSG_PEEK);
check_non_blocking_result(res);
if (res == len)
{
if (recv(socket, msg, len, 0) != len)
error("All or nothing receiving error");
return len;
}
else
return 0;
}
#endif