[Sockets] Multi-Client Server; "Illegal Seek" Fehler



  • Hi,

    ich code gerade eine Server/Client Spiel. (Multiplayer Pong^^)
    Der Server muss dabei 2 Clients gleichzeitig bedienen.
    Dafür verwende ich pthread's aber das ist jetzt ja egal 😉

    Mein Problem sind die Sockets:

    Ich hab mir eine Klasse für alle Socketaufgaben geschrieben:

    /* PongNet Server
       Licensed under the GNU/GPL
       (c) 2005 Sven Peter
       see LICSENSE for more informations
    */
    
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <unistd.h>
    #include <netinet/in.h>
    #include <string>
    #include <arpa/inet.h>
    #include <errno.h>
    
    #include <iostream>
    
    class Socket
    {
    	public:
    	//variables
    	int s;
    	struct sockaddr_in addr;
    
    	//functions
    	Socket();
    	~Socket();
    
    	void create(void);
    	bool connect(const std::string ip, const unsigned short int port);
    	bool bind(const unsigned short int port);
    	bool listen(void);
    	bool accept(Socket& new_sock);
    	bool recv(std::string& data, bool& closed);
    	bool send(const std::string data);
    	void close(void);
    };
    
    #define DEBUG_MODE
    
    Socket::Socket()
    {
    }
    
    Socket::~Socket()
    {
    	//close the socket
    	::close(this->s);
    }
    
    void Socket::create()
    {
    	int on = 1;
    
    	//prepare socket
    	this->s = socket(AF_INET, SOCK_STREAM, 0);
    	setsockopt(this->s, SOL_SOCKET, SO_REUSEADDR, ( const char* ) &on, sizeof ( on ) );
    }
    
    void Socket::close()
    {
    	//close the socket
    	::shutdown(this->s,0);
    }
    
    bool Socket::connect(const std::string ip, const unsigned short int port)
    {
    	//prepare connection
    	this->addr.sin_addr.s_addr = inet_addr(ip.c_str());
    	this->addr.sin_port = port;
    	this->addr.sin_family = AF_INET;
    
    	//connect
    	if(::connect(this->s, (struct sockaddr*) &this->addr, sizeof(addr)) == -1)
    	{
    		return false;
    	}
    	else
    	{
    		return true;
    	}
    }
    
    bool Socket::bind(const unsigned short int port)
    {
    	//prepare bind
    	this->addr.sin_addr.s_addr = INADDR_ANY;
    	this->addr.sin_port = port;
    	this->addr.sin_family = AF_INET;
    
    	//bind
    	if(::bind(this->s, (struct sockaddr*) &this->addr, sizeof(addr)) == -1)
    	{
    		return false;
    	}
    	else
    	{
    		return true;
    	}
    }
    
    bool Socket::listen(void)
    {
    	if(::listen(this->s,4) == -1)
    	{
    		return false;
    	}
    	else
    	{
    		return true;
    	}
    }
    
    bool Socket::accept(Socket& new_sock)
    {
    	socklen_t len;
    
    	new_sock.s = ::accept(this->s, (struct sockaddr*) &this->addr, ( socklen_t * ) &this->addr);
    
    	if(new_sock.s <= 0)
    	{
    		return false;
    	}
    	else
    	{
    		return true;
    	}
    }
    
    bool Socket::recv(std::string& data, bool& socket_closed)
    {
    	char buff[1025];
    	int bytes;
    
    	bytes = ::recv(this->s, buff, 1024,0);
    
    	buff[bytes] = '\0';
    
    	data = buff;
    
    #ifdef DEBUG_MODE
    			std::cout << "The following packet has been recieved (" << bytes << " :: " << errno << "):" << std::endl;
    			std::cout << data << std::endl;
    			perror("Result");
    #endif
    
    	if(bytes == -1)
    	{
    		return false;
    	}
    	else if(bytes == 0)
    	{
    		socket_closed = true;
    		return false;
    	}
    	else
    	{
    		return true;
    	}
    }
    
    bool Socket::send(std::string data)
    {
    	int bytes;
    
    	bytes = ::send(this->s, data.c_str(), data.size(), 0);
    
    #ifdef DEBUG_MODE
    			std::cout << "The following packet has been sent(" << bytes << " :: " << errno << "):" << std::endl;
    			std::cout << data << std::endl;
    			perror("Result");
    #endif
    
    	if(bytes == -1)
    	{
    		return false;
    	}
    	else
    	{
    		return true;
    	}
    }
    

    Wenn ich mich jetzt mit einem Client verbinden will:

    #include <iostream>
    #include <string>
    #include "socket.h"
    int main()
    {
    	std::string ip = "127.0.0.1";
    	std::string packet = "100|test";
    
    	Socket sock;
    	sock.create();
    
    	sock.connect(ip,1234);
    
    	sock.send(packet);
    
    	while(true)
    	{
    		status = sock.recv(buff,closed);
    		if(closed == true)
    		{
    			perror("socket closed");
    			exit(1);
    		}
    		else if(status == false)
    		{
    			perror("recv() failed!");
    			exit(1);
    		}
    		else
    		{
    			std::cout << buff;
    		}
    	}
    }
    

    Bekomme ich als ausgabe:

    The following packet has been sent(8 :: 29):
    100|test
    Result: Illegal seek
    sent packet: Illegal seek
    The following packet has been recieved (4 :: 29):
    101|
    Result: Illegal seek
    
    101|
    
    The following packet has been recieved (0 :: 29):
    
    Result: Illegal seek
    socket closed: Illegal seek
    

    auf der Serverseite:

    The following packet has been recieved (8 :: 0):
    100|test
    Result: Success
    Playerid: 0 true!
    The following packet has been sent(4 :: 29):
    101|
    Result: Illegal seek
    The following packet has been recieved (16777215 :: 9):
    
    Result: Bad file descriptor
    

    Jetzt meine Frage:
    Was bedeutet dieses "Illegal Seek"?

    Achja, der Quellcode ist mit der GNU GPL lizensiert, also falls iregndwer ihn verwenden will kann er dies gerne tun 😉



  • Also ich glaube nicht, dass jemand hier im Forum große Lust hat, 5 Seiten Quelltext durchzuarbeiten. Ich schlage vor, du kreist den Fehler erst einmal mit 'nem Debugger (oder printf()-Anweisungen nach jedem Schritt) ein und fragst dann noch einmal konkreter nach.

    Martin



  • Ruf doch perror nur auf wenn recv oder send wirklich fehlschlägt.


Anmelden zum Antworten