PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : tastenabfragen, die nicht blockierend sind, aber auch nicht die CPU belasten



doomcalyptica
27-06-2005, 20:24
hallo ^^,
der titel mag etwas seltsam erscheinen aber dennoch brauch ich so etwas ..
und zwar möchte ich einen kleien chat programmieren und nun hängt es etwas am client, der schreiben soll und text empfangen soll "zur gleichen zeit" ... schön währe es natürlich wenn man das irgenwie in select mit einbauen könnte (blockiert zwar aber solange man was eingeben kann und trozdem was empfängt , währe es ja in ordnung ^^)


#ifdef _WIN32
// wenn windows !!!

#pragma comment( lib, "ws2_32.lib" )
#include <windows.h>
#include <winsock2.h>
#include <stdio.h>
#include <stdlib.h>

int startWinsock(void) {WSADATA wsa;return WSAStartup(MAKEWORD(2,0),&wsa);}

#else
//in dem fall linux !!
#include <stdio.h>
#include <sys/socket.h>
#include <sys/type.h>
#include <netinet/in.h>
#endif

#define MAX_CLIENTS 10

int main() {
#ifdef _WIN32
// nur windows !!!
startWinsock();
#endif
char buf[1000];
SOCKET sock_client;
SOCKADDR_IN addr_client;
int test;
FD_SET fd_lese;

sock_client=socket(AF_INET,SOCK_STREAM,0);
if(sock_client==INVALID_SOCKET)
return -1;
addr_client.sin_addr.s_addr=inet_addr("192.168.1.2");
addr_client.sin_family=AF_INET;
addr_client.sin_port=htons(5000);
if(connect(sock_client,&addr_client,sizeof(SOCKADDR_IN))==INVALID_SOCKET)
return -1;
FD_ZERO(fd_lese);
FD_SET(sock_client,&fd_lese);

else {
while(1) {
if(select(0,&fd_lese,NULL,NULL,NULL))==INVALID_SOCKET) {
printf("verbindung unterbochen\n");
return 0;
}

scanf("%s",buf);
test=send(sock_client,buf,strlen(buf),0);
if(test==INVALID_SOCKET||test==0) {
printf("server down\n");
return -1;
}
test=recv(sock_client,buf,strlen(buf),0);
if(test==INVALID_SOCKET||test==0) {
printf("server down\n");
return -1;
}


}
}
return 0;
}

das programm empfängt garnichts ^^
weil das scanf blockiert ... wie kann ich aber jetzt eien eingabe ermöglichen und gleichzeitig entfernen ?
brauch ich select dazu ? (denk mal nicht ^^)
schön währe es, wenn ich die eingabe durch eine taste wie "#" aktiviere
kann mir jemand eine code schnippsel dazu basteln ?

doomcalyptica
27-06-2005, 20:43
ehm, sorry der code geht jetzt aber ^^


#ifdef _WIN32
// wenn windows !!!

#pragma comment( lib, "ws2_32.lib" )
#include <windows.h>
#include <winsock2.h>
#include <stdio.h>
#include <stdlib.h>

int startWinsock(void) {WSADATA wsa;return WSAStartup(MAKEWORD(2,0),&wsa);}

#else
//in dem fall linux !!
#include <stdio.h>
#include <sys/socket.h>
#include <sys/type.h>
#include <netinet/in.h>
#endif

#define MAX_CLIENTS 10

int main() {
#ifdef _WIN32
// nur windows !!!
startWinsock();
#endif
char buf[1000];
SOCKET sock_client;
SOCKADDR_IN addr_client;
int test;


sock_client=socket(AF_INET,SOCK_STREAM,0);
if(sock_client==INVALID_SOCKET)
return -1;
addr_client.sin_addr.s_addr=inet_addr("192.168.1.2");
addr_client.sin_family=AF_INET;
addr_client.sin_port=htons(5000);
if(connect(sock_client,&addr_client,sizeof(SOCKADDR_IN))==INVALID_SOCKET)
return -1;

else {
while(1) {

scanf("%s",buf);
test=send(sock_client,buf,strlen(buf),0);
if(test==INVALID_SOCKET||test==0) {
printf("server down\n");
return -1;
}
test=recv(sock_client,buf,strlen(buf),0);
if(test==INVALID_SOCKET||test==0) {
printf("server down\n");
return -1;
}else{
buf[test]='\0';
printf("%s\n",buf);
}


}
}
return 0;
}

gibt es ein scanf mit timeout oder so etwas in der art, (da währe mein problem ja gelöst ^^)

7.e.Q
28-06-2005, 13:24
Du kannst das mit select() machen. Nimm einfach den Filedeskriptor 0 (Standard Input) mit in das Read FD Set mit auf! Dann kommt select() immer zurück, sobald du eine Taste drückst (bzw. Daten auf einem anderen FD anstehen).

Soweit ich weiß, müssten sich die Daten dann per read() vom FD einlesen lassen. Das ist allerdings sehr lowlevel. Eventuell geht das auch, daß du auf Rückkehren von select() wegen eines Tastendrucks scanf aufrufst, welches dann die Daten von der Tastatur entgegen nimmt. Allerdings blockiert das dann, bis zu Enter drückst. Zeichenweises Einlesen geht da am saubersten mit read(), denke ich. Aber Achtung! Du darfst dann immer nur ein Zeichen mit read() einlesen, weil read sonst auch blockiert, bis du die entsprechende Anzahl Zeichen eingegeben hast. Alles Stolperfallen, über die ich schon geflogen bin... :(