Пример #1
0
/* Look up various bits of information related to a Socket instance and store
   them in the private member variables for future use. If this has already
   been called on a specific instance, do nothing. */
static AValue SocketGetInfo(AThread *t, AValue *frame)
{
    if (AMemberDirect(frame[0], SOCKET_DST_ADDRESS) == ANil) {
        AValue v;
        SOCKLEN_T len;
        struct sockaddr_in address;
        int handle;

        handle = AGetInt(t, AMemberDirect(frame[0], A_FILE_ID));

        len = sizeof(address);
        if (getsockname(handle, (struct sockaddr *)&address, &len) < 0)
            return RaiseSocketError(t);

        v = AMakeInt(t, ntohs(address.sin_port));
        ASetMemberDirect(t, frame[0], SOCKET_SRC_PORT, v);
        /* FIX: inet_ntoa is not thread-safe */
        v = AMakeStr(t, inet_ntoa(address.sin_addr));
        ASetMemberDirect(t, frame[0], SOCKET_SRC_ADDRESS, v);

        len = sizeof(address);
        if (getpeername(handle, (struct sockaddr *)&address, &len) < 0)
            return RaiseSocketError(t);

        v = AMakeInt(t, ntohs(address.sin_port));
        ASetMemberDirect(t, frame[0], SOCKET_DST_PORT, v);
        /* FIX: inet_ntoa is not thread-safe */
        v = AMakeStr(t, inet_ntoa(address.sin_addr));
        ASetMemberDirect(t, frame[0], SOCKET_DST_ADDRESS, v);
    }

    return ANil;
}
Пример #2
0
void NetworkCommandBuffer::Think()
{
	SDLNet_SocketSet set;

	set = SDLNet_AllocSocketSet ( 1 );
	if ( !set )
	{
		RaiseSocketError ( "SDLNet_AllocSocketSet" );
	}
	SocketSetEncapsulator free_on_quit ( set );
	if ( SDLNet_TCP_AddSocket ( set, socket ) < 0 )
		{
			RaiseSocketError ( "SDLNet_TCP_AddSocket" );
		}
	int numready = SDLNet_CheckSockets ( set, 0 );
	for ( ; numready == 1; numready = SDLNet_CheckSockets ( set, 0 ) )
		{
			char msg;
			int nbread = SDLNet_TCP_Recv ( socket, &msg, 1 );
			if ( nbread < 0 )
			{
				RaiseSocketError ( "SDLNet_TCP_Recv: " );
			}
			else if ( nbread == 0 )
			{
				std::cout << "SDLNet_TCP_Recv: Unexpected read of size 0\n";
				throw ReadSocketError();
			}
			if ( debug_all_message )
			{
				if ( msg < 32 )
					std::cout << "Read: 0x" << ( int ) msg << "\n";
				else
					std::cout << "Read: " << msg << "\n";
			}
			if (current_command_size > 0)
				AddCharToBuffer ( msg );
			else
				AddCharToCommandSize( msg );
		}
	if ( numready < 0 )
	{
		std::cout << "SDLNet_CheckSockets: " << SDLNet_GetError() << "\n";
		perror ( "SDLNet_CheckSockets" );
		throw ReadSocketError();
	}
}
Пример #3
0
/* socket::GetHostName() */
static AValue SocketGetHostName(AThread *t, AValue *frame)
{
    char buf[MAX_ADDRESS_LEN];

    if (gethostname(buf, sizeof(buf)) < 0)
        return RaiseSocketError(t);

    return AMakeStr(t, buf);
}
Пример #4
0
/* Socket create(destination, port[, buffering]) */
static AValue SocketCreate(AThread *t, AValue *frame)
{
    char addressStr[MAX_ADDRESS_LEN];
    int handle;
    struct sockaddr_in address;
    int port;

    /* Get host name. */
    AGetStr(t, frame[1], addressStr, MAX_ADDRESS_LEN);

    /* Get port number. */
    port = AGetInt(t, frame[2]);

    /* Get buffering mode. */
    if (AIsDefault(frame[3]))
        frame[1] = AGlobalByNum(AUnbufferedNum);
    else if (frame[3] == AGlobalByNum(AUnbufferedNum) ||
             frame[3] == AGlobalByNum(ALineBufferedNum) ||
             frame[3] == AGlobalByNum(ABufferedNum))
        frame[1] = frame[3];
    else
        return ARaiseValueError(t, "Invalid arguments");

    frame[2] = AGlobalByNum(AInputNum);
    frame[3] = AGlobalByNum(AOutputNum);
    frame[4] = AGlobalByNum(ANarrowNum);

    if (AIsError(AStreamCreate(t, frame)))
        return AError;

    /* Initialize address structure. */
    memset(&address, 0, sizeof(address));
    address.sin_family = AF_INET;
    address.sin_port = htons(port);

    /* GetHostByName can handle both numeric IP addresses and host names. */
    if (!GetHostByName(t, addressStr, &address.sin_addr))
        return AError;

    /* Create socket. */
    handle = socket(AF_INET, SOCK_STREAM, 0);
    if (handle < 0)
        return RaiseSocketError(t);

    /* Create connection. */
    for (;;) {
        int status;

        AAllowBlocking();
        status = connect(handle, (struct sockaddr *)&address,
                         sizeof(address));
        AEndBlocking();

        if (status < 0) {
            if (errno == EINTR) {
                if (AIsInterrupt && AHandleInterrupt(t))
                    return AError;
                else
                    continue;
            } else {
                RaiseSocketError(t);
                close(handle);
                return AError;
            }
        }
        break;
    }

    frame[1] = AMakeInt(t, handle);
    ASetMemberDirect(t, frame[0], A_FILE_ID, frame[1]);

    return frame[0];
}