开发者

socket identifier equals -1

Somehow, someway the socket is -1. It shouldn't be because my client program connects and send information but is stopped by SIGPIPE signal. When I debug the server I see t开发者_开发知识库hat accept returns -1. I have got no idea why. If you no, answer please.

client.cpp

using namespace std;
using namespace msg;
using namespace dataExchange;

int main() {
  Connection con("127.0.0.1", 123456);
  Annoucement ann;
  ann.set_typ(Annoucement::AKCJA);
  con.send(ann);
}

server.cpp

using namespace std;
using namespace msg;
using namespace dataExchange;

int main() {
  Server server(123456);
  while(1) {
    Connection con = server.accept();
    Annoucement ann = con.receive();
    cout << ann.typ() << endl;
  }
}

connect.cpp

using namespace msg;
using namespace google::protobuf;
using namespace google::protobuf::io;

namespace dataExchange {

  class SocketMaintenance {
  protected:
    sockaddr_in addr;
    int s;
  public:
    SocketMaintenance(const unsigned int port) {
      memset(&addr, 0, sizeof(addr));
      addr.sin_family = AF_INET;
      addr.sin_port = htons(port);
      s = socket(AF_INET, SOCK_STREAM, 0);
    }
    SocketMaintenance(const sockaddr_in Addr, const int Socket) {
      addr = Addr;
      s = Socket;
    }
    SocketMaintenance(const SocketMaintenance& source) {
      addr = source.addr;
      s = source.s;
    }
    ~SocketMaintenance() {
      close(s);
    }
    void write(const char* buffer, const int n) {
      ::write(s, buffer, n);
    }
  };

  class Connection : public SocketMaintenance {
    FileOutputStream* raw_output;
    FileInputStream* raw_input;
    char buffer[1024];
  public:
    Connection(const char* IP, const unsigned int port) : SocketMaintenance(port) {
      if(inet_pton(AF_INET, IP, &addr.sin_addr)<=0) {
    throw WrongAddress();
      }
      if(connect(s, (sockaddr*)&addr, sizeof(addr))<0) {
    throw ConnectFailed();
      }
      raw_output = new FileOutputStream(s);
      raw_input = new FileInputStream(s);
    }
    Connection(const SocketMaintenance& source) : SocketMaintenance(source) {}
    ~Connection() {
      delete raw_output;
    }
    void send(const Message& msg) throw(EmptyMessage)  {
      CodedOutputStream* coded_output = new CodedOutputStream(raw_output);
      int n = msg.ByteSize();
      if(n<=0) throw EmptyMessage();
      coded_output->WriteVarint32(n);
      delete coded_output;
      raw_output->Flush();
      msg.SerializeToArray(buffer, n);
      SocketMaintenance::write(buffer, n);
    }
    Annoucement receive() throw() {
      CodedInputStream* coded_input = new CodedInputStream(raw_input);
      google::protobuf::uint32 n;
      coded_input->ReadVarint32(&n);
      char *b;
      int m;
      coded_input->GetDirectBufferPointer((const void**)&b, &m);
      Annoucement ann;
      ann.ParseFromArray(b, n);
      return ann;
    }

  };

  class Server : public SocketMaintenance {
  public:
    Server(const unsigned int port) : SocketMaintenance(port) {
      addr.sin_addr.s_addr = htonl(INADDR_ANY);
      if(bind(s, (struct sockaddr *)&addr, sizeof(addr))<0) {
    throw BindFailed();
      }
      if(listen(s, 5)<0) {
    throw ListenFailed();
      }
    }
    Connection accept() throw() {
      sockaddr_in client;
      socklen_t client_len;
      int client_socket = ::accept(s, (sockaddr*)&client, &client_len);
      return Connection(SocketMaintenance(client, client_socket));
    }
  };

}

I have tested this code before I rearranged it into classes. Then it worked flawlessly.


One glaring issue I see is that your port is invalid. sockaddr_in::sin_port is a uint16_t, whose largest value can possibly be 65536. Best case, you're truncating your port on the call to htons, which should result in 57920.

In regards to why the accept is failing, -1 indicates an error occured, and you should check the value of errno to see why.

From man 2 accept:

RETURN VALUE On success, accept() returns a non-negative integer that is a descriptor for the accepted socket. On error, -1 is returned, and errno is set appropriately.


At a guess, somewhere in there you are passing a socket class object by value and its destructor is closing the socket prematurely. I couldn't be bothered wading through the code to find out if that is the case, but some observations:

  • don't allocate things with new unless you absolutely have to
  • don't implement copy constructors if all they do is what the default copy constructor should do
  • DO prevent copying of socket objects by declaring copy constructors and assignment operators as private and then not implementing them
  • don't "rearrange" things into classes - either start out writing classes from the get go, or just write procedural code
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜