Здравствуйте, Crackjack, Вы писали:
C>Здравствуйте, maxlosyam, Вы писали:
M>>вот тут http://www.tenouk.com/Module41.html есть пример сервера на select, все делается в одном потоке. просто почитайте поищите про select.
C>Вообще select введен для совместимости с кодами UNIX. Для Win родное — это OVERLAPED, а для улутшения работы с OVERLAPED применяется IOCP.
C>В принципе когда у машины один процессор с одним ядром, то при хорошей реализации однопоточное приложение будет работать быстрее, чем многопоточное. Только реализовать такое приложение сложнее, чем многопоточное. Это я к вопросу о тысячах подключений и по потоку на обработку каждого подключения.
Вы абсолютно правы, потому что данный пример из ссылки, был переделан под винду (с минимальными изменениями) но и это не спасло "отца русской демократии" (с)
Вот к слову код
#include <winsock2.h>
#include <stdio.h>
#include <time.h>
#include <process.h>
#pragma comment(lib,"ws2_32.lib")
/*******select.c*********/
/*******Using select() for I/O multiplexing */
/* port we're listening on */
#define PORT 2020
int main(int argc, char *argv[])
{
WSADATA lpData;
/* master file descriptor list */
fd_set master;
/* temp file descriptor list for select() */
fd_set read_fds;
/* server address */
struct sockaddr_in serveraddr;
/* client address */
struct sockaddr_in clientaddr;
/* maximum file descriptor number */
int fdmax;
/* listening socket descriptor */
int listener;
/* newly accept()ed socket descriptor */
int newfd;
/* buffer for client data */
char buf[1024];
int nbytes;
/* for setsockopt() SO_REUSEADDR, below */
int yes = 1;
int addrlen;
int i, j;
/* clear the master and temp sets */
FD_ZERO(&master);
FD_ZERO(&read_fds);
WSAStartup(MAKEWORD(2, 2), &lpData);
/* get the listener */
if((listener = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
WSACleanup();
printf("Server-socket() error lol!");
/*just exit lol!*/
exit(1);
}
printf("Server-socket() is OK...\n");
/*"address already in use" error message */
if(setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, (const char *)&yes, sizeof(int)) == -1)
{
printf("Server-setsockopt() error lol!");
exit(1);
}
printf("Server-setsockopt() is OK...\n");
/* bind */
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = INADDR_ANY;
serveraddr.sin_port = htons(PORT);
memset(&(serveraddr.sin_zero), '\0', 8);
if(bind(listener, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) == -1)
{
printf("Server-bind() error lol!");
exit(1);
}
printf("Server-bind() is OK...\n");
/* listen */
if(listen(listener, 10) == -1)
{
printf("Server-listen() error lol!");
exit(1);
}
printf("Server-listen() is OK...\n");
/* add the listener to the master set */
FD_SET(listener, &master);
/* keep track of the biggest file descriptor */
fdmax = listener; /* so far, it's this one*/
/* loop */
for(;;)
{
/* copy it */
read_fds = master;
if(select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1)
{
printf("Server-select() error lol!");
exit(1);
}
printf("Server-select() is OK...\n");
/*run through the existing connections looking for data to be read*/
for(i = 0; i <= fdmax; i++)
{
if(FD_ISSET(i, &read_fds))
{ /* we got one... */
if(i == listener)
{
/* handle new connections */
addrlen = sizeof(clientaddr);
if((newfd = accept(listener, (struct sockaddr *)&clientaddr, &addrlen)) == -1)
{
printf("Server-accept() error lol!");
}
else
{
printf("Server-accept() is OK...\n");
FD_SET(newfd, &master); /* add to master set */
if(newfd > fdmax)
{ /* keep track of the maximum */
fdmax = newfd;
}
printf("%s: New connection from %s on socket %d\n", argv[0], inet_ntoa(clientaddr.sin_addr), newfd);
}
}
else
{
/* handle data from a client */
if((nbytes = recv(i, buf, sizeof(buf), 0)) <= 0)
{
/* got error or connection closed by client */
if(nbytes == 0)
/* connection closed */
printf("%s: socket %d hung up\n", argv[0], i);
else
printf("recv() error lol!");
/* remove from master set */
FD_CLR(i, &master);
}
else
{
/* we got some data from a client*/
for(j = 0; j <= fdmax; j++)
{
/* send to everyone! */
if(FD_ISSET(j, &master))
{
/* except the listener and ourselves */
if(j != listener && j != i)
{
if(send(j, buf, nbytes, 0) == -1)
printf("send() error lol!");
}
}
}
}
}
}
}
}
WSACleanup();
return 0;
}
Я там ниже код давал. Не помогло?