/tags/MAIN/nil/src/tcp_socket.cpp
C++ | 203 lines | 126 code | 42 blank | 35 comment | 41 complexity | 06915dc380a2e2160403fb36999846bd MD5 | raw file
Possible License(s): AGPL-1.0, GPL-3.0
- /***************************************************************************
- tcp_socket.cpp - TCP socket handling
- --------------------------------------------------------------------------
- begin : 1999-11-17
- by : Flemming Frandsen
- email : dion@swamp.dk
- last changed : 2004-01-25
- by : Christoph Brill
- email : egore@gmx.de
- copyright : (C) 1999 by Flemming Frandsen
- email : dion@swamp.dk
- ***************************************************************************/
- #include "tcp_socket.h"
- #include "fluff.h"
- #include "systemheaders.h"
- int recv_timeout(int s, void *buf, int len, unsigned int timeout)
- {
- int bytes_left = len;
- int bytes_done = 0;
- unsigned int start_time = time_ms();
- while (1) {
- int recv_result = recv(s,((char*)buf)+bytes_done,bytes_left,0);
- if (recv_result < 0) {
- logmsg(lt_error,"recv(%i,((char*)%x)+%i,%i,0); returned %i (%s)",s,(int)buf,bytes_done,bytes_left,errno,strerror(errno));
- return -2; //uh, it went bad.
- } else if (recv_result > 0) {
- bytes_done += recv_result;
- bytes_left -= recv_result;
-
- //If this was the last bit of data, return immediatly.
- if (bytes_left == 0) return 0;
-
- //reset the timer once we get a bit of data.
- start_time = time_ms();
- }
-
- //see if we have timed out
- if (time_elapsed(start_time,time_ms()) > timeout) return -1;
- }
- return 0;
- }
- int send_timeout(int s, void *buf, int len, unsigned int timeout)
- {
- int bytes_left = len;
- int bytes_done = 0;
- unsigned int start_time = time_ms();
- while (1) {
- int send_result = send(s,((char*)buf)+bytes_done,bytes_left,0);
- if (send_result < 0) {
- logmsg(lt_error,"send(%i,((char*)%x)+%i,%i,0); returned %i (%s)",s,(int)buf,bytes_done,bytes_left,errno,strerror(errno));
- return -2; //uh, it went bad.
- } else if (send_result > 0) {
- bytes_done += send_result;
- bytes_left -= send_result;
-
- //If this was the last bit of data, return immediatly.
- if (bytes_left == 0) return 0;
-
- //reset the timer once we get a bit of data.
- start_time = time_ms();
- }
-
- //see if we have timed out
- if (time_elapsed(start_time,time_ms()) > timeout) return -1;
- }
- return 0;
- }
- //-------------------------------------------------------------------------
- int Tcp_socket::send(void *buf, int len, unsigned int timeout)
- {
- int result = send_timeout(socket, buf, len, timeout);
- if (result == -1)
- logmsg(lt_error,"Time out while writing to the socket.");
- else if (result == -2)
- logmsg(lt_error,"Error while writing to the socket: %i",result);
- else if (result < 0)
- logmsg(lt_error,"AAARGH!.");
- if (result < 0) bedone = true;
- return result;
- }
- //-------------------------------------------------------------------------
- int Tcp_socket::recv(void *buf, int len, unsigned int timeout)
- {
- int result = recv_timeout(socket, buf, len, timeout);
- if (result == -1)
- logmsg(lt_error,"Time out while reading from the socket.");
- else if (result == -2)
- logmsg(lt_error,"Error while reading from the socket: %i",result);
- else if (result < 0)
- logmsg(lt_error,"AAARGH!.");
- if (result < 0) bedone = true;
- return result;
- }
- //-------------------------------------------------------------------------
- int Tcp_socket::send(Serializer_reader *serializer_reader)
- {
- int net_length = htonl(serializer_reader->getlength());
- int error = send(&net_length,sizeof(net_length));
- if (error) return error;
- //send the state data itself.
- error = send(serializer_reader->getbuffer(),serializer_reader->getlength());
- if (error) return error;
- return 0;
- }
- //-------------------------------------------------------------------------
- int Tcp_socket::recv(Serializer_writer *serializer_writer, int max_sane_size)
- {
- int net_length = -1;
- int error = recv(&net_length,sizeof(net_length));
- if (error) return error;
- //check the length of the data for bogosity
- int length = ntohl(net_length);
- if (length < 0 || length > max_sane_size) {
- logmsg(lt_error,"In int Tcp_socket::recv(Serializer_writer) we got a length of %i, this is wrong, expect the world to end.",length);
- return -50;
- }
- //get the data itself
- error = recv(serializer_writer->setbuffer(length),length);
- if (error) return error;
- return 0;
- }
- //-------------------------------------------------------------------------
- int Tcp_socket::send(int value)
- {
- int net_value = htonl(value);
- int error = send(&net_value,sizeof(net_value));
- if (error) return error;
- return 0;
- }
- //-------------------------------------------------------------------------
- int Tcp_socket::recv(int &value)
- {
- int net_value = -1;
- int error = recv(&net_value,sizeof(net_value));
- if (error) return error;
- value = ntohl(net_value);
- return 0;
- }
- //-------------------------------------------------------------------------
- int Tcp_socket::send(Serializable *object)
- {
- //get the objects state
- reader.clear();
- object->serialize(&reader);
- return send(&reader);
- }
- //-------------------------------------------------------------------------
- int Tcp_socket::recv(Serializable *object)
- {
- //get the object state
- int error = recv(&writer);
- if (error) return error;
- object->serialize(&writer);
- //check the serializer for error conditions.
- if (!writer.empty()) {
- logmsg(lt_error,"In Tcp_socket we got too many bytes for the obejct to eat, this is wrong, expect the world to end.");
- return -51;
- }
- if (writer.empty_read()) {
- logmsg(lt_error,"In Tcp_socket we got too few bytes for the obejct to eat, this is wrong, expect the world to end.");
- return -52;
- }
- return 0;
- }