#endif\r
// Windows linux \r
\r
-const int NumberOfThreads = 1;\r
+const int NumberOfThreads = 2;\r
\r
HANDLE g_ComplitionPort;\r
-HANDLE *g_pThreads;\r
+HANDLE g_pThreads[NumberOfThreads];\r
\r
#define ASSERT assert\r
\r
struct sockaddr addressFromString(char *address, int port)\r
{\r
- unsigned int b1,b2,b3,b4;\r
+ unsigned int b1,b2,b3,b4;\r
\r
- struct sockaddr_in socket_address;\r
- struct sockaddr *socket_address_ptr = (struct sockaddr*)&socket_address;\r
+ struct sockaddr_in socket_address;\r
+ struct sockaddr *socket_address_ptr = (struct sockaddr*)&socket_address;\r
\r
- memset(&socket_address, 0, sizeof(socket_address));\r
- socket_address.sin_family = AF_INET;\r
- socket_address.sin_port = htons((u_short)port);\r
-\r
-\r
- sscanf(address, "%d.%d.%d.%d",&b1, &b2, &b3, &b4);\r
- socket_address.sin_addr.s_addr = b4 * 256 * 256 *256 +\r
- b3 * 256 * 256 + \r
- b2 * 256 +\r
- b1;\r
- \r
- return *socket_address_ptr;\r
+ memset(&socket_address, 0, sizeof(socket_address));\r
+ socket_address.sin_family = AF_INET;\r
+ socket_address.sin_port = htons((u_short)port);\r
+\r
+\r
+ sscanf(address, "%d.%d.%d.%d",&b1, &b2, &b3, &b4);\r
+ socket_address.sin_addr.s_addr = b4 * 256 * 256 *256 +\r
+ b3 * 256 * 256 + \r
+ b2 * 256 +\r
+ b1;\r
+ \r
+ return *socket_address_ptr;\r
}\r
\r
\r
void *Buffer; // The data to send\r
int DataSize;\r
DWORD NumberOfBytesSent;\r
- int RemainingSends;\r
- int SendsInAir; // Curently sent data\r
- CRITICAL_SECTION Lock;\r
- HANDLE SendDoneEvent;\r
+ static int s_RemainingSends;\r
+ static int s_SendsInAir; // Curently sent data (debug only)\r
+ static CRITICAL_SECTION s_Lock;\r
+ static HANDLE s_SendDoneEvent;\r
\r
};\r
\r
+int OverlappedSend::s_RemainingSends;\r
+int OverlappedSend::s_SendsInAir; // Curently sent data (debug only)\r
+CRITICAL_SECTION OverlappedSend::s_Lock;\r
+HANDLE OverlappedSend::s_SendDoneEvent;\r
+\r
\r
DWORD WINAPI WorkerThreadFunc( LPVOID lpParam )\r
{\r
ASSERT(ret != 0);\r
pOverLappedSend = CONTAINING_RECORD(lpOverlapped, OverlappedSend, Overlapped);\r
// Work on the object itself:\r
- EnterCriticalSection(&pOverLappedSend->Lock);\r
- pOverLappedSend->SendsInAir--;\r
- ASSERT(pOverLappedSend->SendsInAir ==0); // Only one thread\r
- if (pOverLappedSend->RemainingSends > 0) {\r
+ EnterCriticalSection(&pOverLappedSend->s_Lock);\r
+ pOverLappedSend->s_SendsInAir--;\r
+ if (pOverLappedSend->s_RemainingSends > 0) {\r
// do the next send\r
WSABUF Buffers;\r
Buffers.len = pOverLappedSend->DataSize;\r
Buffers.buf = (char *) pOverLappedSend->Buffer;\r
- pOverLappedSend->SendsInAir++;\r
- pOverLappedSend->RemainingSends--;\r
+ pOverLappedSend->s_SendsInAir++;\r
+ pOverLappedSend->s_RemainingSends--;\r
\r
iRet = WSASend(\r
pOverLappedSend->Socket,\r
\r
} else {\r
// Nothing more to send - signal compleation and exit\r
- SetEvent(pOverLappedSend->SendDoneEvent);\r
+ SetEvent(pOverLappedSend->s_SendDoneEvent);\r
ContinueLoop = false;\r
}\r
- LeaveCriticalSection(&pOverLappedSend->Lock);\r
+ LeaveCriticalSection(&pOverLappedSend->s_Lock);\r
if (!ContinueLoop) {\r
break;\r
}\r
\r
void CreateComplitionPort(SOCKET newfd)\r
{\r
- g_pThreads = new HANDLE [NumberOfThreads];\r
- ASSERT(g_pThreads != NULL);\r
-\r
\r
g_ComplitionPort = CreateIoCompletionPort((HANDLE)newfd, NULL, NULL, 2);\r
if(g_ComplitionPort == NULL) {\r
exit(1);\r
}\r
\r
- // Create the threads that will work on the complitions\r
- g_pThreads[0] = CreateThread(NULL, 0 ,WorkerThreadFunc ,NULL, 0,NULL );\r
+\r
+ for (int i=0; i <NumberOfThreads;i++ ) {\r
+ // Create the threads that will work on the complitions\r
+ g_pThreads[i] = CreateThread(NULL, 0 ,WorkerThreadFunc ,NULL, 0,NULL ); \r
+ }\r
+\r
+\r
+\r
\r
\r
}\r
\r
void CloseComplitionPort()\r
{\r
- //??? Post a complition thread end message\r
\r
+ // Post a complition thread end message\r
+ for (int i=0; i <NumberOfThreads - 1;i++ ) {\r
+ // Sending an overlapped of NULL works, since the\r
+ // reciever tests first for end of test\r
+ BOOL ret = PostQueuedCompletionStatus(\r
+ g_ComplitionPort,\r
+ 0,\r
+ NULL,\r
+ NULL\r
+ );\r
+ ASSERT(ret != 0);\r
+ }\r
WaitForMultipleObjects(NumberOfThreads,g_pThreads, TRUE, INFINITE);\r
CloseHandle(g_ComplitionPort);\r
\r
}\r
\r
-void SendDataOverlapped(SOCKET newfd, double NumberOfBuffers, double BufferSize, BOOL SendPacketNumber)\r
+void SendDataOverlapped(SOCKET newfd, int NumberOfOverlappedSend, double NumberOfBuffers, double BufferSize, BOOL SendPacketNumber)\r
{\r
- // We will start with one operations simultaniously\r
int i ;\r
- double d;\r
VOID *buffer = NULL;\r
double elapsed, acc = 0;\r
- WSAOVERLAPPED wsa;\r
OverlappedSend *pOverLappedSend = NULL;\r
BOOL ret;\r
- memset(&wsa, 0, sizeof wsa);\r
\r
- buffer = malloc ((size_t)BufferSize);\r
- if (buffer == NULL) {\r
- printf("Error allocating buffer\n");\r
- exit(1);\r
- }\r
+ printf("Starting to send asyncroniously (%d overlapped) %lf messages of size %lf\n", NumberOfOverlappedSend, NumberOfBuffers, BufferSize );\r
+\r
\r
CreateComplitionPort(newfd);\r
+ pOverLappedSend->s_RemainingSends = (size_t)NumberOfBuffers;\r
+ pOverLappedSend->s_SendsInAir = 1; // To force a simulate of the compleation\r
+ InitializeCriticalSection(&pOverLappedSend->s_Lock);\r
+ pOverLappedSend->s_SendDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL);\r
+ \r
+ double Start = GetTimeMs();\r
+\r
+ for(i = 0; i < NumberOfOverlappedSend; i++) {\r
\r
- pOverLappedSend = new OverlappedSend;\r
+ buffer = new char [(size_t)BufferSize];\r
+ if (buffer == NULL) {\r
+ printf("Error allocating buffer\n");\r
+ exit(1);\r
+ }\r
\r
- // Set it's fields\r
- memset(&pOverLappedSend->Overlapped, 0, sizeof (pOverLappedSend->Overlapped));\r
- pOverLappedSend->Socket = newfd;\r
- pOverLappedSend->Buffer = buffer;\r
- pOverLappedSend->DataSize = (size_t)BufferSize;\r
- pOverLappedSend->RemainingSends = (size_t)NumberOfBuffers;\r
- pOverLappedSend->SendsInAir = 1; // To force a simulate of the compleation\r
- InitializeCriticalSection(&pOverLappedSend->Lock);\r
- pOverLappedSend->SendDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL);\r
+ pOverLappedSend = new OverlappedSend;\r
\r
- double Start = GetTimeMs();\r
- // Post the message that will do the first send\r
- ret = PostQueuedCompletionStatus(\r
+ // Set it's fields\r
+ memset(&pOverLappedSend->Overlapped, 0, sizeof (pOverLappedSend->Overlapped));\r
+ pOverLappedSend->Socket = newfd;\r
+ pOverLappedSend->Buffer = buffer;\r
+ pOverLappedSend->DataSize = (size_t)BufferSize;\r
+\r
+ // Post the message that will do the first send\r
+ ret = PostQueuedCompletionStatus(\r
g_ComplitionPort,\r
(DWORD)BufferSize,\r
NULL,\r
&pOverLappedSend->Overlapped\r
);\r
- ASSERT(ret != 0);\r
+ ASSERT(ret != 0);\r
+\r
+ }\r
\r
// wait for the send \r
- WaitForSingleObject(pOverLappedSend->SendDoneEvent, INFINITE);\r
+ WaitForSingleObject(pOverLappedSend->s_SendDoneEvent, INFINITE);\r
elapsed = (GetTimeMs() - Start) / 1000;\r
printf("Finishd sending correctly %f mbytes/sec\n", NumberOfBuffers * BufferSize /elapsed/1024/1024 );\r
CloseComplitionPort();\r
//Cleanup:\r
- free(buffer);\r
-\r
-\r
+ for(i = 0; i < NumberOfOverlappedSend; i++) {\r
+ delete []pOverLappedSend->Buffer;\r
+ delete pOverLappedSend;\r
+ }\r
}\r
\r
\r
exit(1);\r
}\r
\r
- printf("Starting to send %lf messages of size %lf\n", NumberOfBuffers, BufferSize );\r
+ printf("Starting to send syncroniously %lf messages of size %lf\n", NumberOfBuffers, BufferSize );\r
\r
i = 0;\r
\r
else {\r
acc += read1;\r
\r
-// printf("read returned %d \"%c%c%c%c\"\n",read1,\r
-// buffer[0],buffer[1], buffer[2], buffer[3]);\r
+// printf("read returned %d \"%c%c%c%c\"\n",read1,\r
+// buffer[0],buffer[1], buffer[2], buffer[3]);\r
}\r
}\r
\r
void PrintUsage(char *name)\r
{\r
printf("The program might be used in client or server mode\n");\r
- printf("usage is %s <server> <port number>\n", name);\r
+ printf("usage is %s <server> <port number>\n", name);\r
printf("usage is %s <client> <ip> <port number> <option number> <WritePacketNumber> <UseOverlappedSend> <Number of packets> <PacketSize>\n", name);\r
printf("The option will be sent to the remote side\n");\r
- printf("Available options are:\n");\r
- printf(" 1 - just recieve packets forever (the other side will send xxx bytes yyy times)\n");\r
- printf(" 2 - send xxx bytes yyy times (based on input from network)\n");\r
+ printf("Available options are:\n");\r
+ printf(" 1 - just recieve packets forever (the other side will send xxx bytes yyy times)\n");\r
+ printf(" 2 - send xxx bytes yyy times (based on input from network)\n");\r
printf(" WritePacketNumber can be 0 (no) or 1 (yes)\n");\r
- printf(" UseOverlappedSend can be 0 (no) or 1 (yes)\n");\r
+ printf(" UseOverlappedSend can be 0 (no) or > 0 (number of operations to use)\n");\r
\r
}\r
\r
int Connect(int argc, char *argv[])\r
{\r
- struct sockaddr server_addr;\r
- int port = atoi(argv[3]);\r
+ struct sockaddr server_addr;\r
+ int port = atoi(argv[3]);\r
int ret;\r
SOCKET s;\r
int Send = 0;\r
int BufferSize, NumberOfBuffers;\r
int result = 0;\r
- BOOL SendPacketNumber;\r
- int UseOverlappedSend = 0;\r
+ bool SendPacketNumber;\r
+ int NumberOfOverlappedSend = 0;\r
\r
if (argv[4][0] == '1') {\r
Send = 1;\r
}\r
\r
if (argv[5][0] == '0') {\r
- SendPacketNumber = FALSE;\r
+ SendPacketNumber = false;\r
}else if (argv[5][0] == '1') {\r
- SendPacketNumber = TRUE;\r
+ SendPacketNumber = true;\r
} else {\r
printf("Error - don't know if to send the packet number\n");\r
exit(1);\r
}\r
\r
- if (argv[6][0] == '0') {\r
- UseOverlappedSend = FALSE;\r
- }else if (argv[6][0] == '1') {\r
- UseOverlappedSend = TRUE;\r
- } else {\r
- printf("Error - don't know if to send overlapped or not\n");\r
+ NumberOfOverlappedSend = atoi(argv[6]);\r
+\r
+ if ((NumberOfOverlappedSend > 0 ) && (SendPacketNumber == true)) {\r
+ printf("Warning, Sending packet number is not supported yet in overlapped send\n");\r
exit(1);\r
}\r
- \r
-\r
+ \r
NumberOfBuffers = atoi(argv[7]);\r
BufferSize = atoi(argv[8]);\r
\r
- printf("Using port %d %s %s %s NumberOfBuffers = %d , BufferSize = %d \n", \r
+ printf("Using port %d %s %s %s NumberOfBuffers = %d , BufferSize = %d \n", \r
port, \r
Send == 1 ? "sending" : "recieving", \r
SendPacketNumber ? "Packets Are filed with data" : "Packets are not filled with data",\r
- UseOverlappedSend ? "Using overlapped send" : "not using overlapped send", \r
+ NumberOfOverlappedSend > 0 ? "Using overlapped send" : "not using overlapped send", \r
NumberOfBuffers,\r
BufferSize\r
);\r
// or recieve(=0),UseOverlapped ,NumberOfBuffers, BufferSize,\r
if (Send) {\r
char message[60];\r
- sprintf(message, "1,%d,%d,%d,0,", UseOverlappedSend,NumberOfBuffers, BufferSize);\r
+ sprintf(message, "1,%d,%d,%d,0,", NumberOfOverlappedSend ,NumberOfBuffers, BufferSize);\r
ret = send(s, message, strlen (message), 0);\r
if (ret != strlen (message)) {\r
printf("Error in send winsock error=%d\n", WSAGetLastError());\r
} \r
} else {\r
char message[60];\r
- sprintf(message, "2,%d,%d,%d,%d,",UseOverlappedSend, NumberOfBuffers, BufferSize, SendPacketNumber);\r
+ sprintf(message, "2,%d,%d,%d,%d,",NumberOfOverlappedSend, NumberOfBuffers, BufferSize, SendPacketNumber ? 1 : 0);\r
ret = send(s, message, strlen (message), 0);\r
if (ret != strlen (message)) {\r
printf("Error in send winsock error=%d\n", WSAGetLastError());\r
}\r
}\r
if (Send) {\r
- if (UseOverlappedSend) {\r
- SendDataOverlapped(s, NumberOfBuffers, BufferSize, SendPacketNumber);\r
+ if (NumberOfOverlappedSend > 0 ) {\r
+ SendDataOverlapped(s, NumberOfOverlappedSend, NumberOfBuffers, BufferSize, SendPacketNumber);\r
} else {\r
SendData(s, NumberOfBuffers, BufferSize, SendPacketNumber);\r
}\r
printf("Error reading data 1\n");\r
exit(1);\r
}\r
+// printf("%c",Data[i]);\r
if (Data[i] == ',') break;\r
i++;\r
if (i == 20) {\r
BufferSize = ReadNumber(newfd);\r
SendPacketNumber = ReadNumber(newfd);\r
\r
- printf("%s ,%s Using overlapped Send,NumberOfBuffers = %d , BufferSize =%d PacketsFilled=%s \n", \r
+ printf("%s ,%d overlapped Send,NumberOfBuffers = %d , BufferSize =%d PacketsFilled=%s \n", \r
option == 2 ? "sending" : "recieving",\r
- UseOverlappedSend ? "" : "not",\r
+ UseOverlappedSend,\r
NumberOfBuffers,\r
BufferSize,\r
SendPacketNumber ? "true" : "false"\r
);\r
\r
if (option == 1) RecvData(newfd, NumberOfBuffers, BufferSize);\r
- if (option == 2) SendData(newfd, NumberOfBuffers, BufferSize, SendPacketNumber);\r
-\r
+ if (option == 2) {\r
+ if (UseOverlappedSend > 0) {\r
+ SendDataOverlapped(newfd, UseOverlappedSend, NumberOfBuffers, BufferSize, SendPacketNumber);\r
+ } else {\r
+ SendData(newfd, NumberOfBuffers, BufferSize, SendPacketNumber);\r
+ }\r
+ }\r
+ \r
ret = CloseSocket(newfd);\r
if (ret == 0) {\r
printf("CloseSocket succeeded\n");\r
{\r
int error; \r
\r
- if (argc < 3) {\r
- PrintUsage(argv[0]);\r
- return 1;\r
- }\r
+ if (argc < 3) {\r
+ PrintUsage(argv[0]);\r
+ return 1;\r
+ }\r
\r
#ifdef _WIN32\r
{\r
WSADATA wsaData;\r
\r
- error = WSAStartup( MAKEWORD( 2, 2 ), &wsaData);\r
- if (error) {\r
- printf("Error in WSAStartup: winsock error=%d\n", WSAGetLastError());\r
- return 1;\r
- }\r
+ error = WSAStartup( MAKEWORD( 2, 2 ), &wsaData);\r
+ if (error) {\r
+ printf("Error in WSAStartup: winsock error=%d\n", WSAGetLastError());\r
+ return 1;\r
+ }\r
}\r
#endif \r
if (!_stricmp(argv[1],"client")) {\r
Server(argc, argv);\r
} else {\r
printf("Unknowion option %s", argv[1]);\r
- PrintUsage(argv[0]);\r
+ PrintUsage(argv[0]);\r
\r
}\r
- SOCKET s;\r
+ SOCKET s;\r
s = socket (AF_INET_FAMILY, SOCK_STREAM, 0);\r
CloseSocket(s); \r
//printf("calling WSACleanup\n ");\r
int ret = WSACleanup ();\r
//printf("ret = %d", ret);\r
- //Sleep(10000);\r
return 0;\r
}\r
\r