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:
82
piethernet.h
Executable file → Normal file
82
piethernet.h
Executable file → Normal 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
|
||||
|
||||
Reference in New Issue
Block a user