Files
MP-SPDZ/Networking/sockets.h
2020-03-20 20:31:25 +11:00

164 lines
3.4 KiB
C++

#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 *str1,const char *str2);
void error(const char *str);
void set_up_server_socket(sockaddr_in& dest,int& consocket,int& main_socket,int Portnum);
void close_server_socket(int consocket,int main_socket);
void set_up_client_socket(int& mysocket,const char* hostname,int Portnum);
void close_client_socket(int socket);
/* Send and receive 8 bit integers */
template<class T>
void send(T socket,int a);
template<class T>
void receive(T socket,int& a);
// same for words
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);
void send_ack(int socket);
int get_ack(int socket);
extern unsigned long long sent_amount, sent_counter;
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);
}
sent_amount += len;
sent_counter++;
}
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