Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Nazwa modu³u: Server.c
- //
- // Opis:
- // Prosta aplikacja serwera TCP, akceptuj¹ca nachodz¹ce
- // po³¹czenia klientów. Po ustanowieniu po³¹czenia
- // uruchamiany jest w¹tek odczytuj¹cy dane przes³ane przez
- // klienta i odsy³aj¹cy je z powrotem.
- //
- // Opcje wiersza poleceñ:
- // server [-p:port] [-i:IP]
- // -p:port Numer nas³uchuj¹cego portu
- // -i:IP Nas³uchuj¹cy interfejs
- //
- #include <winsock2.h>
- #include <stdio.h>
- #include <stdlib.h>
- #define DEFAULT_PORT 5150
- #define DEFAULT_BUFFER 4096
- int iPort = DEFAULT_PORT; // Port nas³uchuj¹cy klientów
- BOOL setInterface = FALSE; // Czy okreœlono interfejs s³uchaj¹cy?
- char szAddress[128];
- char szMessage[1024];
- char szBuffer[2048]; // Interfejs nas³uchuj¹cy klientów
- //
- // Funkcja: usage
- //
- // Opis:
- // Wydruk informacji o dzia³aniu programu
- //
- void usage()
- {
- printf("u¿ycie: server [-p:port] [-i:IP]\n\n");
- printf(" -p:port Numer nas³uchuj¹cego portu\n");
- printf(" -i:IP Nas³uchuj¹cy interfejs\n");
- ExitProcess(1);
- }
- //
- // Funkcja: ValidateArgs
- //
- // Opis:
- // Analiza argumentów wiersza poleceñ i ustalenie wartoœci
- // niektórych znaczników globalnych, decyduj¹cych o wykonaniu
- // okreœlonych czynnoœci.
- //
- void ValidateArgs(int argc, char **argv)
- {
- int i;
- for(i = 1; i < argc; i++)
- {
- if ((argv[i][0] == '-') || (argv[i][0] == '/'))
- {
- switch (argv[i][1])
- {
- case 'p':
- iPort = atoi(&argv[i][3]);
- break;
- case 'i':
- setInterface = TRUE;
- if (strlen(argv[i]) > 3)
- strcpy(szAddress, &argv[i][3]);
- break;
- default:
- usage();
- break;
- }
- }
- }
- }
- //
- // Funkcja: ClientProcedure
- //
- // Opis:
- // Ta funkcja jest wywo³ywana w postaci w¹tku obs³uguj¹cego
- // dane po³¹czenie klienta. Przekazany parametr jest uchwytem
- // gniazda zwróconym przez wywo³anie funkcji accept(). Ta
- // funkcja czyta dane nades³ane przez klienta i odsy³a je
- // z powrotem.
- //
- DWORD WINAPI ClientProcedure(LPVOID lpParam)
- {
- SOCKET sock=(SOCKET)lpParam;
- char szBuff[DEFAULT_BUFFER];
- int ret,
- nLeft,
- idx;
- while(1)
- {
- // Wykonanie blokuj¹cej funkcji recv ()
- //
- ret = recv(sock, szBuff, DEFAULT_BUFFER, 0);
- if (ret == 0) // Zamkniêcie uzgodnione
- break;
- else if (ret == SOCKET_ERROR)
- {
- printf("Funkcja recv() zakoñczona b³êdem: %d\n",
- WSAGetLastError());
- break;
- }
- szBuff[ret] = '\0';
- printf("ODBIÓR: '%s'\n", szBuff);
- /*
- // Odes³anie danych
- //
- nLeft = ret;
- idx = 0;
- // Sprawdzenie, czy zapisaliœmy wszystkie dane
- //
- while(nLeft > 0)
- {
- ret = send(sock, &szBuff[idx], nLeft, 0);
- if (ret == 0)
- break;
- else if (ret == SOCKET_ERROR)
- {
- printf("Funkcja send() zakoñczona"
- " b³êdem: %d\n",
- WSAGetLastError());
- break;
- }
- nLeft -= ret;
- idx += ret;
- }*/
- }
- return 0;
- }
- DWORD WINAPI WriterProcedure(LPVOID lpParam)
- {
- SOCKET sClient=(SOCKET)lpParam;
- char szBuff[DEFAULT_BUFFER];
- int ret,
- nLeft,
- idx;
- while(1)
- {
- scanf("%s", szMessage);
- int i = 0;
- ret = send(sClient, szMessage, strlen(szMessage), 0);
- if (ret == 0)
- break;
- else if (ret == SOCKET_ERROR)
- {
- printf("Funkcja send() zakoñczona b³êdem: %d\n",
- WSAGetLastError());
- break;
- }
- printf("Wys³ano %d bajtów\n", ret);
- }
- return 0;
- }
- //
- // Funkcja: main
- //
- // Opis:
- // W¹tek g³ówny. Inicjacja interfejsu Winsock, analiza
- // argumentów wiersza poleceñ, utworzenie nas³uchuj¹cego
- // gniazda, zwi¹zanie go z adresem lokalnym i oczekiwanie
- // na po³¹czenia klientów.
- //
- int main(int argc, char **argv)
- {
- WSADATA wsd;
- SOCKET sListen,
- sClient;
- struct sockaddr_in local,
- client;
- int iAddrSize;
- HANDLE hThread;
- HANDLE hThread2;
- DWORD dwThreadId;
- DWORD dwThreadId2;
- ValidateArgs(argc, argv);
- if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
- {
- printf("Nie mo¿na wczytaæ biblioteki Winsock!\n");
- return 1;
- }
- // Utworzenie nas³uchuj¹cego gniazda
- //
- sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
- if (sListen == SOCKET_ERROR)
- {
- printf("Funckja socket() zakoñczona b³êdem: %d\n",
- WSAGetLastError());
- return 1;
- }
- // Wybór lokalnego interfejsu, z którym zostanie
- // zwi¹zane gniazdo
- //
- if (setInterface) // jeœli okreœlono interfejs, s³uchaj na nim
- {
- local.sin_addr.s_addr = inet_addr(szAddress);
- //if (local.sin_addr.s_addr == INADDR_NONE)
- // usage();
- }
- else // jeœli nie okreœlono interfejsu, to s³uchaj na wszystkich
- {
- local.sin_addr.s_addr = htonl(INADDR_ANY);
- }
- local.sin_family = AF_INET;
- local.sin_port = htons((u_short)iPort);
- if (bind(sListen, (struct sockaddr *)&local,
- sizeof(local)) == SOCKET_ERROR)
- {
- printf("Funkcja bind() zakoñczona b³êdem: %d\n",
- WSAGetLastError());
- return 1;
- }
- listen(sListen, 8);
- //
- // Oczekiwanie na ¿¹dania klientów w ci¹g³ej pêtli. Po
- // wykryciu próby po³¹czenia, utworzenie w¹tku i przekazanie
- // jego uchwytu.
- //
- while (1)
- {
- iAddrSize = sizeof(client);
- sClient = accept(sListen, (struct sockaddr *)&client,
- &iAddrSize);
- if (sClient == INVALID_SOCKET)
- {
- printf("Funkcja accept() zakoñczona b³êdem: %d\n",
- WSAGetLastError());
- break;
- }
- printf("Zaakceptowano klienta: %s:%d\n",
- inet_ntoa(client.sin_addr), ntohs(client.sin_port));
- hThread = CreateThread(NULL, 0, ClientProcedure,
- (LPVOID)sClient, 0, &dwThreadId);
- if (hThread == NULL)
- {
- printf("Funkcja CreateThread() zakoñczona b³êdem: %d\n",
- WSAGetLastError());
- break;
- }
- hThread2 = CreateThread(NULL, 0, WriterProcedure,
- (LPVOID)sClient, 0, &dwThreadId2);
- if (hThread2 == NULL)
- {
- printf("Funkcja CreateThread() zakoñczona b³êdem: %d\n",
- WSAGetLastError());
- break;
- }
- CloseHandle(hThread); // zwalnia uchwyt, nie powoduje zakonczenia watku
- CloseHandle(hThread2);
- }
- closesocket(sListen);
- WSACleanup();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement