Enviado em 21/08/2015 - 09:33h
Bom dia, estou tentado fazer um class de socket, são duas class uma que é mais procima do c, que eu ja fis duas aplicacoes servidores e nao bugo, e outra que fasilita ao criar sockets tcp, essa ultima funciona como cliente mas como servidor, por algum motivo nao funciona, e essa segunda class usa a primeira class que funciona, as Class:
#ifdef WIN32
#include <winsock2.h>
#progma comment(lib, "ws2_32.lib")
#else
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>
#include <string>
#include <string.h>
#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
const int MAXHOSTNAME = 200;
const int MAXCONNECTIONS = 5;
const int MAXRECV = 500;
#define SOCKET_ERROR 0xFFFFFFFF
#define INVALID_SOCKET 0xFFFFFFFF
#endif
#include <iostream>
class Socket{
#ifdef WIN32
SOCKET sock;
WSADATA wsa;
int start();
void end();
int foiCriado;
typedef SOCKET ret;
#else
int sock;
sockaddr_in addr;
typedef int ret;
#endif
public:
Socket();
virtual ~Socket();
bool create(int domain, int type, int protocol);
bool bind(const int port);
bool listen();
bool accept(Socket& s);
bool connect(const std::string host, const int port);
bool send(const std::string s);
bool send(char* s, int lenght);
int recv(std::string& s);
int recv(char* s, int lenght);
void setBlocking(const bool isBlocking);
bool isValid(){ return sock != -1; }
int getFd(){ return sock; }
//sockaddr_in getAddr();
//void setAddr(sockaddr_in addr);
};
Socket::Socket(){
#ifdef WIN32
foiCriado = 0;
#endif
sock = -1;
memset(&addr, 0, sizeof(addr));
}
Socket::~Socket(){
if(!isValid() == false){
close(sock);
}
#ifdef WIN32
if(foiCriado){
end();
}
#endif
}
bool Socket::create(int domain = AF_INET, int type = SOCK_STREAM, int protocol = 0){
sock = ::socket(domain, type, protocol);
if(!isValid()){
return false;
}
return true;
}
bool Socket::bind(const int port){
if(!isValid()){
return false;
}
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = ::htons(port);
int r = ::bind(sock, (struct sockaddr *)&addr, sizeof(addr));
if(r == -1){
return false;
}
return true;
}
bool Socket::listen(){
if(!isValid()){
return false;
}
int r = ::listen(sock, MAXCONNECTIONS);
if(r == -1){
return false;
}
return true;
}
bool Socket::accept(Socket& s){
socklen_t addr_length = sizeof(addr);
sockaddr_in remoto;
s.sock = ::accept(sock, (sockaddr *)&remoto, &addr_length);
s.addr = remoto;
std::cout << "Fd de novo: " << s.sock << std::endl;
if(s.sock <= 0){
return false;
}
return true;
}
bool Socket::send(const std::string s){
int status = ::send(sock, s.c_str(), s.size(), MSG_NOSIGNAL);
if (status == -1){
return false;
}
return true;
}
bool Socket::send(char* s, int lenght){
int status = ::send (sock, s, lenght, MSG_NOSIGNAL);
if (status == -1){
return false;
}
return true;
}
int Socket::recv(std::string& s){
char buf[MAXRECV + 1];
s = "";
memset(buf, 0, MAXRECV+1);
std::cout << "Vamos la: " << sock << std::endl;
int status = ::recv(sock, buf, MAXRECV, 0);
if(status == -1){
return -1;
} else if(status == 0){
return 0;
} else {
s = buf;
return status;
}
}
int Socket::recv(char* s, int lenght){
int status = ::recv(sock, s, lenght, 0);
if(status == -1){
return -1;
} else if(status == 0){
return 0;
} else {
return status;
}
}
bool Socket::connect(const std::string host, const int port){
if(!isValid()){
return false;
}
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
int status = inet_pton(AF_INET, host.c_str(), &addr.sin_addr);
if(status == -1){
return false;
}
status = ::connect(sock, (sockaddr *)&addr, sizeof(addr));
if(status == -1){
return false;
}
return true;
}
void Socket::setBlocking(const bool isBlocking){
int opts;
opts = fcntl(sock, F_GETFL);
if(opts < 0 ){
return;
}
if(isBlocking)
opts = ( opts | O_NONBLOCK );
else
opts = ( opts & ~O_NONBLOCK );
fcntl(sock, F_SETFL, opts);
}
#include "socket.h"
#include <string>
#include <iostream>
#include <errno.h>
class SocketException{
std::string m_s;
public:
SocketException(std::string s){ m_s = s; };
~SocketException(){};
std::string description(){ return m_s; }
};
class DisconnectdException{};
class SocketIO{
protected:
Socket socket;
public:
SocketIO(Socket &so){
socket = so;
std::cout << "So essa ves: " << so.getFd() << std::endl;
}
SocketIO();
virtual ~SocketIO(){}
void sendBytes(char *s, int len);
void sendString(const std::string s);
int recvBytes(char *s, int len);
std::string recvString();
Socket getSocket(){ return socket; }
};
class ClientSocket: public SocketIO{
public:
ClientSocket(const std::string host, int port);
};
class ServerSocket: public SocketIO{
public:
ServerSocket(int port);
SocketIO* accept();
};
SocketIO::SocketIO(){
if(!socket.create()){
throw SocketException("Erro create");
}
}
void SocketIO::sendBytes(char *s, int len){
int r = socket.send(s, len);
if(r == -1){
throw SocketException("Erro send");
} else if(r == 0){
throw DisconnectdException();
}
}
void SocketIO::sendString(const std::string s){
int r = socket.send(s);
if(r == -1){
throw SocketException("Erro send");
} else if(r == 0){
throw DisconnectdException();
}
}
int SocketIO::recvBytes(char* s, int len){
int r = socket.recv(s, len);
if(r == -1){
throw SocketException("Erro recv");
} else if(r == 0){
throw DisconnectdException();
}
return r;
}
std::string SocketIO::recvString(){
std::string str = "";
std::cout << "Outra vez: " << socket.getFd() << std::endl;
int r = socket.recv(str);
std::cout << "R: " << r << std::endl;
if(r == -1){
std::string sss = strerror(errno);
throw SocketException("Recv: "+sss);
} else if(r == 0){
throw DisconnectdException();
}
return str;
}
ClientSocket::ClientSocket(const std::string host, int port) : SocketIO() {
if((socket.connect(host, port)) == false){
throw SocketException("Erro connect");
}
}
ServerSocket::ServerSocket(int port){
if((socket.bind(port)) == false){
throw SocketException("Erro bind");
}
if((socket.listen()) == false){
throw SocketException("Erro listen");
}
}
SocketIO* ServerSocket::accept(){
Socket s;
if((socket.accept(s)) == false){
throw SocketException("Erro accept");
}
std::cout << "Fd: " << s.getFd() << std::endl;
SocketIO* ss = new SocketIO(s);
return ss;
}
#include "SocketIO.h"
#include <iostream>
using namespace std;
int main(int argc, char const *argv[]){
try{
ServerSocket server(20200);
cout << "Servidor iniciado!!!" << endl;
Socket s;
if((server.getSocket().accept(s)) == false){
cout << "Erro accept" << endl;
}
SocketIO c(s);
// SocketIO *c = server.accpet() mesmo erro
cout << "Client Conectado!!!" << endl;
cout << "Fd do Client: " << c.getSocket().getFd() << endl;
while(true){
string a = c.recvString();
cout << "Client enviou: " << a << endl;
c.sendString("Ola Client!!!");
}
}catch(SocketException& e){
cout << e.description() << endl;
return 1;
}catch(DisconnectdException& e){
cout << "Cliente desconectou" << endl;
return 1;
}
return 0;
}
Saida do programa:
Servidor iniciado!!!
Fd de novo: 4
So essa ves: 4
Client Conectado!!!
Fd do Client: 4
Outra vez: 4
Vamos la: 4
R: -1
Recv: Bad file descriptor
O erro fala que o descritor do socket nao e bom, mas nao fas sentido pra mi, pos eu fis um cout em todos os lugares que que o descritor aparecia, mas ele e sempre o mesmo.
Se algem pode me ajuda ficarem muito agradecido!