Пример #1
0
	/* Send a request for thread termination. */
	ih->terminate = 1;
#ifdef _WIN32
	WaitForSingleObject (ih->threadId, INFINITE);
#else /* ! _WIN32 */
	pthread_join (ih->threadId, NULL);
#endif /* ! _WIN32 */
	free (ih);
	return 0;
}


#ifdef _WIN32
static DWORD WINAPI ircThread (LPVOID ptr)
#else /* ! _WIN32 */
static void *ircThread (void *ptr)
#endif /* ! _WIN32 */
{
	IrcHandle ih = (IrcHandle) ptr;
	char *buffer, *line, *params[IRC_MAXPARAMS], *p;
	int rcvd, offset = 0;

	buffer = xmalloc (513 * sizeof (char));
	line = xmalloc (513 * sizeof (char));

	/* Read data from the IRC server -- 2 seconds timeout. */
	while ((rcvd = socketsRecvNB (ih->socket, buffer + offset,
		513 - 1 - offset, 2000)) != 0)
	{
		if (ih->terminate)
		{
			socketsShutdown (ih->socket, SOCKETS_SHUT_BOTH);
			/* For the case we get here again. */
			ih->terminate = 0;
			continue;
		}
		if (rcvd == -1)
		{
			if (socketsGetLastError () == SOCKETS_ETIMEDOUT)
				continue;
			else
				break;
		}

		rcvd += offset;
		buffer[rcvd] = '\0';

		/* Process the lines. */
		offset = 0;
		while ((p = strstr (buffer + offset, "\r\n")) != NULL)
		{
			struct IrcMessage msg = {NULL, NULL, NULL, 0};

			memcpy (line, buffer + offset, p - buffer - offset);
			line[p - buffer - offset] = '\0';
			offset = p - buffer + 2;

			/* TODO: A callback event. */

			msg.params = params;
			ircParseLine (line, &msg);

			ih->callback (ih, IRC_EVENT_MESSAGE, &msg, ih->userData);
		}

		/* If data still remain, move them to the beginning. */
		if (offset < rcvd)
			memmove (buffer, buffer + offset, rcvd - offset);
		offset = rcvd - offset;
	}

	free (line);
	free (buffer);
	socketsClose (ih->socket);

	ih->callback (ih, IRC_EVENT_DISCONNECT, NULL, ih->userData);
	return 0;
}
/*
 *  ======== main ========
 */
int main(int argc, char *argv[])
{
    int i;
    int sockfd = 0;
    int bytes_read, total_bytes_read, bytes_sent;
    struct addrinfo hints;
    struct addrinfo *results = NULL;
    int status = EXIT_SUCCESS;
    int count = 0;
    int id;
    int value;
    unsigned int sleepTime = 1000;
    unsigned int buffSize  = MAXBUF;
    char *buffer = NULL;
    time_t start;
    start = time(NULL);

    /* parameter check */
    if (argc < 4 || argc > 6) {
        printf("usage: %s <IPv4 or IPv6 addr> <port> <id> -l[length] -s[sleep in uS]\n", argv[0]);
        status = EXIT_FAILURE;
        goto QUIT;
    }

    id = atoi(argv[3]);

    /* Parse options */
    i = argc - 1;
    while ((i > 3) && (argv[i][0] == '-')) {
        switch (argv[i][1]) {
            case 'l':
                buffSize = atoi(&argv[i][2]);
                break;
            case 's':
                sleepTime = atoi(&argv[i][2]);
                break;
            default:
                printf("Valid options are -l[length] and -s[sleep in uS]\n");
                status = EXIT_FAILURE;
                goto QUIT;
        }
        i--;
    }

    buffer = malloc(buffSize);
    if (buffer == NULL) {
        printf("malloc failed\n");
        status = EXIT_FAILURE;
    }
    memset(buffer, 0, buffSize);

    /* initialize sockets environment */
    socketsStartup();

    memset(&hints, 0, sizeof(hints));
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    /*
     * getaddrinfo() fills in the results struct for us appropriately
     * depending on whether the IP address is v4 or v6
     *
     * argv[1] = IPv4 or IPv6 address passed in from command line
     * argv[2] = port number passed in from command line
     */
    value = getaddrinfo(argv[1], argv[2], &hints, &results);

    if (value != 0) {
        fprintf(stderr, "getaddrinfo failed: %d\n", value);
        if (value == -2 || value == 11004) {
            fprintf(stderr, "unrecognized IP address\n");
        }
        status = EXIT_FAILURE;
        goto QUIT;
    }

    /* create socket. ai_family determined for us via getaddrinfo() call */
    if ((sockfd = socket(results->ai_family, SOCK_STREAM, 0)) < 0) {
        fprintf(stderr, "socket failed: %d\n", errno);
        status = errno;
        goto QUIT;
    }

    /* connect. ai_addr set to AF_INET or AF_INET6 by getaddrinfo() call */
    if (connect(sockfd, results->ai_addr, results->ai_addrlen) < 0) {
        printf("connect failed: %d\n", errno);
        status = errno;
        goto QUIT;
    }

    printf("Starting test with a %d uSec delay between transmits\n", sleepTime);

    /* loop */
    i = 0;
    while (1) {
        buffer[0] = (char)(++i);
        buffer[buffSize - 1] = (char)~i;
        bytes_sent = send(sockfd, buffer, buffSize, 0);
        if (bytes_sent != buffSize) {
            printf("[id %d] stopping test. send returned %d\n", id, bytes_sent);
            status = EXIT_FAILURE;
            goto QUIT;
        }

        total_bytes_read = 0;
        while (total_bytes_read < buffSize) {
            bytes_read = recv(sockfd, &buffer[total_bytes_read],
			                  buffSize - total_bytes_read, 0);
            if (bytes_read <= 0) {
                printf("[id %d] stopping test. recv returned %d\n", id, bytes_read);
                status = EXIT_FAILURE;
                goto QUIT;
            }
            total_bytes_read += bytes_read;
        }

        count++;

        if (count % 1000 == 0) {
            printf("[id %d] count = %d, time = %ld\n", id, count,
                   time(NULL) - start);
        }

        /* Sleep specified time */
#if defined(__GNUC__) && defined(linux)
        usleep(sleepTime);
#else
        Sleep(sleepTime / 1000);
#endif

    if ((buffer[0] != (char)i) || (buffer[buffSize - 1] != (char)~i)) {
            printf("mismatch buffer[0] = %d, (char)i = %d\n", buffer[0],
                   (char)i);
            printf("mismatch buffer[buffSize - 1] = %d, (char)~i = %d\n",
                   buffer[buffSize - 1], (char)~i);
        }
    }

QUIT:
    /* clean up */
    if (sockfd) {
        closesocket(sockfd);
    }

    if (results) {
        freeaddrinfo(results);
    }

    socketsShutdown();

    if (buffer) {
        free(buffer);
    }
    return (status);
}