Mail Archives: cygwin/2002/03/05/01:36:05
------=_NextPart_000_0007_01C1C452.1C169950
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: 7bit
To compare the network performance of Cygwin and native WinSock, I wrote the
attached code.
Under the three compiler (MinGW 1.1 GCC 2.95, Cygwin GCC 2.95, GCC 2.96 of
Red Hat 7.1) I used, I typed only "gcc -Wall fakeweb.c -o fakeweb" to build.
Then I used a Web stress tool to send HTTP GET requests repeatedly (like
ApacheBench, try "ab -n 100 -c 1 x.x.x.x/" on a Linux box).
To my great surprise, the close(socket) operation took EXTREMELY long. It
took 0.11 second (CPU usage was low), while this operation under MinGW 1.1
on the same machine took only 0.00019 second. On another Linux machine,
close took 0.000043 second.
Another problem concerns signal handling. This program could be stopped by
CTRL-C under MinGW and Linux, but it hung and used 100% of CPU under Cygwin
when CTRL-C was hit.
Any help?
Best regards,
Wu Yongwei
P.S. On a last test, one strange thing happened. If I reload 127.0.0.1 in a
local browser quickly while running fakeweb, the displayed close time is
much smaller. It does not work on a remote browser. Just wrote it here and
does not expect an explanation for this point.
------=_NextPart_000_0007_01C1C452.1C169950
Content-Type: application/octet-stream;
name="fakeweb.c"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="fakeweb.c"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#ifdef _WIN32
#include <winsock2.h>
#else
#include <errno.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/socket.h>
#define closesocket close
#define SOCKET int
#define INVALID_SOCKET (-1)
#define SOCKET_ERROR (-1)
#endif
#include "pctimer.h"
char response[] =3D
"<HTML>\r\n"
"<HEAD>\r\n"
"<TITLE>A Test Page</TITLE>\r\n"
"</HEAD>\r\n"
"<BODY>\r\n"
"<P>Hello, this is the <I>FakeWeb</I>-produced page.\r\n"
"<P>Blablablablablablablablabla\r\n"
"<P>Blablablablablablablablabla\r\n"
"<P>Blablablablablablablablabla\r\n"
"<P>Blablablablablablablablabla\r\n"
"<P>Blablablablablablablablabla\r\n"
"<P>Blablablablablablablablabla\r\n"
"<P>Blablablablablablablablabla\r\n"
"<P>Blablablablablablablablabla\r\n"
"<P>Blablablablablablablablabla\r\n"
"<P>Blablablablablablablablabla\r\n"
"<P>Blablablablablablablablabla\r\n"
"<P>Blablablablablablablablabla\r\n"
"<P>Blablablablablablablablabla\r\n"
"<P>Blablablablablablablablabla\r\n"
"<P>Blablablablablablablablabla\r\n"
"<P>Blablablablablablablablabla\r\n"
"<P>Blablablablablablablablabla\r\n"
"<P>Blablablablablablablablabla\r\n"
"<P>Blablablablablablablablabla\r\n"
"<P>Blablablablablablablablabla\r\n"
"<P>Blablablablablablablablabla\r\n"
"<P>Blablablablablablablablabla\r\n"
"<P>Blablablablablablablablabla\r\n"
"<P>Blablablablablablablablabla\r\n"
"<P>Blablablablablablablablabla\r\n"
"<P>Blablablablablablablablabla\r\n"
"<P>Blablablablablablablablabla\r\n"
"<P>Blablablablablablablablabla\r\n"
"<P>Blablablablablablablablabla\r\n"
"</BODY>\r\n"
"</HTML>\r\n";
pctimer_t ta, tr, ts, tc;
int i;
SOCKET ACCEPT(SOCKET s, struct sockaddr *addr, int *addrlen)
{
static int first =3D 1;
pctimer_t t;
SOCKET r;
t =3D pctimer();
r =3D accept(s, addr, addrlen);
if (first)
first =3D 0;
else
ta +=3D pctimer() - t;
return r;
}
int RECV(SOCKET s, char *buf, int len, int flags)
{
pctimer_t t;
int r;
t =3D pctimer();
r =3D recv(s, buf, len, flags);
tr +=3D pctimer() - t;
return r;
}
int SEND(SOCKET s, const char *buf, int len, int flags)
{
pctimer_t t;
int r;
t =3D pctimer();
r =3D send(s, buf, len, flags);
ts +=3D pctimer() - t;
return r;
}
int CLOSESOCKET(SOCKET s)
{
pctimer_t t;
int r;
t =3D pctimer();
r =3D closesocket(s);
tc +=3D pctimer() - t;
return r;
}
void PrintResult(int sig)
{
if (i)
{
printf("%d\n", i);
printf("accept: %f\n", ta / i);
printf("recv: %f\n", tr / i);
printf("send: %f\n", ts / i);
printf("close: %f\n", tc / i);
}
exit(0);
}
int main()
{
SOCKET listenfd, connfd;
struct sockaddr_in servaddr;
char buf[4096];
int nReceived;
#ifdef _WIN32
WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested =3D MAKEWORD(2, 0);
if (WSAStartup(wVersionRequested, &wsaData))
{
printf("WSAStartup error\n");
exit(1);
}
#endif
listenfd =3D socket(AF_INET, SOCK_STREAM, 0);
if (listenfd =3D=3D INVALID_SOCKET)
{
printf("Socket error\n");
exit(1);
}
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family =3D AF_INET;
servaddr.sin_addr.s_addr =3D htonl(INADDR_ANY);
servaddr.sin_port =3D htons(80);
if (bind(listenfd, (void *)&servaddr, sizeof(servaddr)) =3D=3D =
SOCKET_ERROR)
{
printf("Cannot bind port 80\n");
exit(1);
}
if (listen(listenfd, 1) =3D=3D SOCKET_ERROR)
{
printf("Cannot listen on port 80\n");
exit(1);
}
signal(SIGINT, PrintResult);
for (i =3D 0; i < 1; i++)
{
connfd =3D ACCEPT(listenfd, NULL, NULL);
do
{
nReceived =3D RECV(connfd, buf, sizeof buf, 0);
} while (nReceived && nReceived !=3D SOCKET_ERROR && =
buf[nReceived - 1] !=3D '\n');
#ifdef _WIN32
if (nReceived =3D=3D SOCKET_ERROR)
printf("WinSock Error: %d\n", WSAGetLastError());
#else
if (nReceived =3D=3D SOCKET_ERROR)
printf("Socket Error: %d\n", errno);
#endif
sprintf(buf, "HTTP/1.0 200 OK\r\n"
"Content-Length: %d\r\n"
"Content-Type: text/html\r\n"
"\r\n%s",
sizeof response - 1, response);
SEND(connfd, buf, strlen(buf), 0);
CLOSESOCKET(connfd);
}
#ifdef _WIN32
WSACleanup();
#endif
PrintResult(0);
return 0;
}
------=_NextPart_000_0007_01C1C452.1C169950
Content-Type: application/octet-stream;
name="pctimer.h"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="pctimer.h"
/*
* pctimer.h 1.1 02/03/05
*
* Uses Win32 performance counter functions to get a high-resolution timer
*
* By Wu Yongwei
*
*/
#ifndef _PCTIMER_H
typedef double pctimer_t;
#if defined(_WIN32) || defined(__CYGWIN__)
#ifndef _WIN32
#define PCTIMER_NO_WIN32
#endif /* _WIN32 */
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#ifdef PCTIMER_NO_WIN32
#undef PCTIMER_NO_WIN32
#undef _WIN32
#endif /* PCTIMER_NO_WIN32 */
__inline pctimer_t pctimer()
{
static LARGE_INTEGER pcount, pcfreq;
static int initflag;
if (!initflag)
{
QueryPerformanceFrequency(&pcfreq);
initflag++;
}
QueryPerformanceCounter(&pcount);
return (double)pcount.QuadPart / (double)pcfreq.QuadPart;
}
#else /* Win32/Cygwin */
#include <sys/time.h>
__inline pctimer_t pctimer()
{
struct timeval tv;
gettimeofday(&tv, NULL);
return (double)tv.tv_sec + (double)tv.tv_usec / 1000000;
}
#endif /* Win32/Cygwin */
#endif /* _PCTIMER_H */
------=_NextPart_000_0007_01C1C452.1C169950
Content-Type: text/plain; charset=us-ascii
--
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
Bug reporting: http://cygwin.com/bugs.html
Documentation: http://cygwin.com/docs.html
FAQ: http://cygwin.com/faq/
------=_NextPart_000_0007_01C1C452.1C169950--
- Raw text -