分类:
2010-07-05 00:18:12
#if defined(__MINGW32__)
#include
#else
#include
#include
#define closesocket close
#endif
#include
#define D_PORT 4344
#define D_HOST "localhost"
#define D_QUEUE 32
#define D_SOCKETS 16
#define D_INFO 256
#if defined(__MINGW32__)
#define bzero(x,y) memset((x), 0x00, (y))
#define sleep(t) _sleep((t) * 1000)
#endif
int main(int argc, char **argv) {
struct timeval tv;
struct sockaddr_in addr;
struct hostent *host;
unsigned int descriptor;
int result;
int index;
int cycle = 0;
int delay = 0;
unsigned int sockets[D_SOCKETS];
int sockets_index = 0;
unsigned int maximun;
char buffer[D_INFO];
fd_set input;
/* read the delay if any */
if (argc > 1)
delay = atol(argv[1]);
else
delay = 0;
#if defined(__MINGW32__)
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
#endif /* WIN32 */
/* create a socket */
descriptor = socket(PF_INET, SOCK_STREAM, 0);
if (descriptor == -1) {
perror("socket");
return (1);
}
/* get information about the host */
memset(&addr, 0, sizeof(addr));
host = gethostbyname(D_HOST);
if (host == NULL) {
perror("gethostbyname");
closesocket(descriptor);
#if defined(__MINGW32__)
WSACleanup();
#endif
return (1);
}
/* bind the socket to an address and port */
memcpy(&addr.sin_addr, host->h_addr_list[0], sizeof(host->h_addr_list[0]));
addr.sin_family = AF_INET;
addr.sin_port = htons(D_PORT);
result = bind(descriptor, (struct sockaddr *)&addr, sizeof(addr));
if (result == -1) {
perror("bind");
closesocket(descriptor);
#if defined(__MINGW32__)
WSACleanup();
#endif
return (1);
}
/* listen for connections */
result = listen(descriptor, D_QUEUE);
if (result == -1) {
perror("listen");
closesocket(descriptor);
#ifdef WIN32
WSACleanup();
#endif
return (1);
}
memset(sockets, 0, sizeof(sockets));
maximun = descriptor;
result = 0;
while (result != -1) {
FD_ZERO(&input);
FD_SET(descriptor, &input);
for (result = 0; result < sockets_index; result++)
FD_SET(sockets[result], &input);
tv.tv_sec = delay;
tv.tv_usec = 0;
if (delay == -1)
result = select(maximun + 1, &input, NULL, NULL, NULL);
else
result = select(maximun + 1, &input, NULL, NULL, &tv);
switch (result) {
/* error in select */
case -1:
perror("select");
break;
/* nothing to process */
case 0:
break;
/* a number of sockets are ready for reading */
default:
/* check if the descriptor set is our listening one */
if (FD_ISSET(descriptor , &input)) {
sockets[sockets_index] = accept(descriptor, NULL, NULL);
if (sockets[sockets_index] == -1) {
perror("accept");
}
else {
if (sockets[sockets_index] > maximun)
maximun = sockets[sockets_index];
sockets_index++;
}
}
/* one of the sockets is sending data. Find it */
else {
for (index = 0; index < sockets_index; index++) {
if (FD_ISSET(sockets[index], &input)) {
memset(buffer, 0, sizeof(buffer));
/* read information from socket */
result = recv(sockets[index], buffer, sizeof(buffer), 0);
if (result == -1)
perror("recv");
else
printf("Received %d bytes from descriptor %d: %s\n", result, sockets[index], buffer);
}
}
}
}
printf("%d\r", cycle++);
}
for (result = 0; result < sockets_index; result++) {
closesocket(sockets[sockets_index]);
}
closesocket(descriptor);
#if defined(__MINGW32__)
WSACleanup();
#endif
return (0);
}
Ok, here is a very small program. Put this into a file and add it to a VC project, add Ws2_32.lib library for linking, and compile it. Under MinGW, use g++ main.cpp -o main.exe -lwsock32. Execute it. By default, it is a non blocking program. There is a number counting advancing to show you it is not blocking the execution.
Now, run a telnet (telnet localhost 4344). Telnet will connect, and everytime you type something, it will send the letter to the server. You can connect up to 32 telnets. Every time you type a letter, the server prints the socket and the letter. If you see the Task Manager, the program would be taking like 99% of CPU.
If you want your server to wait for 1 second before continuing processing, pass 1 as argument. You will notice I set the new delay. This time, the server will wait for 1 second before continuing with the program. Finally, if you want to make the program blocking, pass -1 as argument. If you check the code, I call select with NULL as last parameter to block it.
Be careful! I am not doing error handling when a telnet shuts down, so if you do it will get mad I hope the example is good enough.
(Edited: Non-Windows support is not tested, too sleepy to turn my other computer on, but should work with one or two hacks).
original url :
Compile command :
i586-mingw32msvc-gcc -g -Wall -o snmp_cm_get_mac.exe test_snmp.c -lwsock32