18.03.2013 - Bug fixes, add in/out speed diagnostic to PIProtocol, fixed PIConsole tab switch segfault, PIObject EVENT / EVENT_HANDLER mechanism update - new EVENT macros that use EVENT_HANDLER with raiseEvent implementation.

This allow compile check event for CONNECT and use EVENT as CONNECT target, also raise event now is simple execute EVENT function.
This commit is contained in:
peri4
2013-03-18 12:07:44 +04:00
parent cfc5eed75e
commit 66c53a27fc
72 changed files with 4407 additions and 960 deletions

82
piethernet.h Executable file → Normal file
View File

@@ -1,7 +1,7 @@
/*
PIP - Platform Independent Primitives
Ethernet, UDP
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -22,61 +22,74 @@
#include "pitimer.h"
#include "piiodevice.h"
#ifndef WINDOWS
# include <netinet/in.h>
# include <arpa/inet.h>
# include <sys/socket.h>
# include <fcntl.h>
#else
# ifdef CC_VC
# include <winsock.h>
# define SHUT_RDWR 2
# else
# include <winsock2.h>
# define SHUT_RDWR SD_BOTH
# endif
#endif
#include "piprocess.h"
class PIEthernet: public PIIODevice
{
friend class PIPeer;
public:
// slot is any function format "bool <func>(void*, uchar*, int)"
PIEthernet(void * data, ReadRetFunc slot);
enum Type {UDP, TCP_Client, TCP_Server};
enum Type {UDP, TCP_Client, TCP_Server, TCP_SingleTCP};
enum Parameters {ReuseAddress = 0x1, Broadcast = 0x2};
PIEthernet(Type type = UDP, void * data = 0, ReadRetFunc slot = 0);
~PIEthernet();
void setReadAddress(PIString ip, int port) {path_ = ip + ":" + PIString::fromNumber(port);}
void setReadAddress(PIString ip_port) {path_ = ip_port;}
void setSendAddress(PIString ip, int port) {ip_s = ip; port_s = port;}
void setSendAddress(PIString ip_port) {parseAddress(ip_port, &ip_s, &port_s);}
void setReadAddress(const PIString & ip, int port) {path_ = ip + ":" + PIString::fromNumber(port);}
void setReadAddress(const PIString & ip_port) {path_ = ip_port;}
void setReadIP(const PIString & ip) {parseAddress(path_, &ip_, &port_); path_ = ip + ":" + PIString::fromNumber(port_);}
void setReadPort(int port) {parseAddress(path_, &ip_, &port_); path_ = ip_ + ":" + PIString::fromNumber(port);}
void setSendAddress(const PIString & ip, int port) {ip_s = ip; port_s = port;}
void setSendAddress(const PIString & ip_port) {parseAddress(ip_port, &ip_s, &port_s);}
void setSendIP(const PIString & ip) {ip_s = ip;}
void setSendPort(int port) {port_s = port;}
PIString readIP() {parseAddress(path_, &ip_, &port_); return ip_;}
int readPort() {parseAddress(path_, &ip_, &port_); return port_;}
PIString sendIP() {return ip_s;}
int sendPort() {return port_s;}
void setParameters(PIFlags<PIEthernet::Parameters> parameters_) {params = parameters_;}
void setParameter(PIEthernet::Parameters parameter, bool on = true) {params.setFlag(parameter, on);}
bool isParameterSet(PIEthernet::Parameters parameter) const {return params[parameter];}
PIFlags<PIEthernet::Parameters> parameters() const {return params;}
//PIByteArray macAddress() {if (!init_) init(); struct ifreq ifr; memset(&ifr, 0, sizeof(ifr)); memcpy(ifr.ifr_name, "eth0", 5); ioctl(sock, SIOCSIFHWADDR, &ifr); return PIByteArray(&ifr.ifr_hwaddr.sa_data, 6);}
Type type() const {return type_;}
bool connect(PIString ip, int port);
bool connect(PIString ip_port) {parseAddress(ip_port, &ip_c, &port_c); return connect(ip_c, port_c);}
bool joinMulticastGroup(const PIString & group);
bool leaveMulticastGroup(const PIString & group);
bool connect(const PIString & ip, int port);
bool connect(const PIString & ip_port) {parseAddress(ip_port, &ip_c, &port_c); return connect(ip_c, port_c);}
bool isConnected() const {return connected_;}
bool listen();
bool listen(PIString ip, int port) {setReadAddress(ip, port); return listen();}
bool listen(PIString ip_port) {setReadAddress(ip_port); return listen();}
bool listen(const PIString & ip, int port) {setReadAddress(ip, port); return listen();}
bool listen(const PIString & ip_port) {setReadAddress(ip_port); return listen();}
PIEthernet * client(int index) {return clients_[index];}
int clientsCount() const {return clients_.size_s();}
PIVector<PIEthernet * > clients() {return clients_;}
bool send(PIString ip, int port, const void * data, int size) {ip_s = ip; port_s = port; return send(data, size);}
bool send(PIString ip_port, const void * data, int size) {parseAddress(ip_port, &ip_s, &port_s); return send(data, size);}
bool send(const PIString & ip, int port, const void * data, int size) {ip_s = ip; port_s = port; return send(data, size);}
bool send(const PIString & ip_port, const void * data, int size) {parseAddress(ip_port, &ip_s, &port_s); return send(data, size);}
bool send(const void * data, int size) {return (write(data, size) == size);}
int read(void * read_to, int max_size);
int write(const void * data, int max_size);
int write(const PIByteArray & data) {return write(data.data(), data.size_s());}
static PIStringList interfaces();
static PIString interfaceAddress(const PIString & interface_);
static PIStringList allAddresses();
protected:
PIEthernet(int sock, PIString ip_port);
virtual void received(void * data, int size) {;}
bool init();
bool openDevice();
bool closeDevice();
@@ -87,17 +100,32 @@ protected:
#endif
void parseAddress(const PIString & ipp, PIString * ip, int * port);
int sock, port_, port_s, port_c, wrote;
int sock, sock_s, port_, port_s, port_c, wrote;
bool connected_;
sockaddr_in addr_, saddr_;
PIString ip_, ip_s, ip_c;
PIThread server_thread_;
PIVector<PIEthernet * > clients_;
#ifdef WINDOWS
PIMap<PIString, SOCKET> leafs;
#endif
PIFlags<PIEthernet::Parameters> params;
Type type_;
private:
static void server_func(void * eth);
static std::string EthErrorString() {
#ifdef WINDOWS
char * msg;
int err = WSAGetLastError();
FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&msg, 0, NULL);
return "code " + itos(err) + " - " + string(msg);
#else
return errorString();
#endif
}
};
#endif // PIETHERNET_H