Kopiuj
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <ifaddrs.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <pthread.h>
#include <termios.h>
static struct termios old, new;
void initTermios(int echo)
{
tcgetattr(0, &old);
new = old;
new.c_lflag &= ~ICANON;
new.c_lflag &= echo ? ECHO : ~ECHO;
tcsetattr(0, TCSANOW, &new);
}
void resetTermios(void)
{
tcsetattr(0, TCSANOW, &old);
}
char getch_(int echo)
{
char ch;
initTermios(echo);
ch = getchar();
resetTermios();
return ch;
}
char getch(void)
{
return getch_(0);
}
char getche(void)
{
return getch_(1);
}
void * client_loop(void * arg)
{
int sck = *((int *) arg);
char buffer[1024];
int rcvd, i;
while (1)
{
rcvd = recv(sck, buffer, 1024, 0);
if (rcvd > 0)
{
for (i = 0; i < rcvd; i++)
{
printf("%c", buffer[i]);
}
}
}
pthread_exit(NULL);
}
int main(int argc, char * argv[])
{
int port, nFoo = 1, nBind, nListen, nClientSocket;
struct sockaddr_in stAddr, stClientAddr;
socklen_t nTmp;
printf("Witaj w programie serwera!\n\n");
printf("Wpisz port na ktorym serwer bedzie nasluchiwal polaczenia\nPort : ");
scanf("%d", &port);
memset(&stAddr, 0, sizeof(struct sockaddr_in));
stAddr.sin_family = AF_INET;
stAddr.sin_addr.s_addr = htonl(INADDR_ANY);
stAddr.sin_port = htons(port);
int nSocket = socket(AF_INET, SOCK_STREAM, 0);
if (nSocket < 0)
{
fprintf(stderr, "%s: Can't create a socket.\n", argv[0]);
exit(1);
}
setsockopt(nSocket, SOL_SOCKET, SO_REUSEADDR, (char *)&nFoo, sizeof(nFoo));
nBind = bind(nSocket, (struct sockaddr *)&stAddr, sizeof(struct sockaddr));
if (nBind < 0)
{
fprintf(stderr, "%s: Can't bind a name to a socket.\n", argv[0]);
exit(1);
}
nListen = listen(nSocket, 5);
if (nListen < 0)
{
fprintf(stderr, "%s: Can't set queue size.\n", argv[0]);
exit(1);
}
while(1)
{
nTmp = sizeof(struct sockaddr);
nClientSocket = accept(nSocket, (struct sockaddr *)&stClientAddr, &nTmp);
if (nClientSocket < 0)
{
fprintf(stderr, "%s: Can't create a connection's socket.\n", argv[0]);
exit(1);
}
printf("[connection from %s] accepted\n", inet_ntoa((struct in_addr)stClientAddr.sin_addr));
pthread_t id;
pthread_create(&id, NULL, client_loop, nClientSocket);
while(1)
{
char temp = getch();
write(nClientSocket, &temp, 1);
}
close(nClientSocket);
}
return 0;
}
Operuję na kompilatorze GCC z cygwina a to znaczy że standard posix ma tutaj zastosowanie. Ja rozumiem że to może być niezgodne ze sztuką ale ja się uczę i pomimo to (jak zresztą powiedział @elwis któremu nota bene jestem wdzięczny że bierze mnie w obronę) prosiłbym o odpowiedzi.
Odpalam telnet który robi mi za klienta. Jak skasuję to:
to normalnie w telnecie pokazuje mi się to co nadaję z tej aplikacji serwera. Natomiast jak już stworzę ten wątek (niewycięta linia kodu) to wówczas aplikacja się zamyka a telnet mówi o przerwanym połączeniu. Dlaczego tak się dzieje. Przecież w tym wątku dodatkowym nie ma nic co by mogło powodować nieprawidłowe działanie, no chyba że o czymś nie wiem. Pomóżcie please.
Mało tego, jak ta funkcja związana z wątkiem dodatkowym nie ma nic w sobie tylko wieczną pętlę załóżmy to telnet również informuje o tym że zerwano połączenie. Wygląda na to że coś pochrzaniłem z tym wątkiem dodatkowym ale co (przekazuję do niego tylko parametr który jest id socketa utworzonego ale już sam fakt takiego przekazania musi powodować wysypywanie się aplikacji - wątpię....) ???