Anzeige:
Ergebnis 1 bis 3 von 3

Thema: tastenabfragen, die nicht blockierend sind, aber auch nicht die CPU belasten

  1. #1
    Registrierter Benutzer
    Registriert seit
    12.09.2004
    Beiträge
    69

    tastenabfragen, die nicht blockierend sind, aber auch nicht die CPU belasten

    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 ^^)
    Code:
    #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 ?

  2. #2
    Registrierter Benutzer
    Registriert seit
    12.09.2004
    Beiträge
    69
    ehm, sorry der code geht jetzt aber ^^
    Code:
    #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 ^^)

  3. #3
    Registrierter Benutzer
    Registriert seit
    02.07.2004
    Beiträge
    456
    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...
    Geändert von 7.e.Q (28-06-2005 um 13:27 Uhr)

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •