tastatur eingabe die nicht blockiert



  • 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 ?



  • Verpack das Senden Empfangen und das Ein/Ausgeben in 3 threads
    Ein thread hört uaf den Eingang, der zweite thread schreibt auf den Ausgang und der dritte thread nimmt die Daten von der
    Tastatur entgegen und gibt die eingekommenen Daten auf dem Bildchirm aus

    Allerdings ist dieses Forum nicht der richtige Platz dafür, dah multithtreading OS spezifisch und es in deinem Fall besser
    in WinApi aufgehoben ist.

    Falls einer der Admins derselben Meinung ist, bitte verschieben.



  • hmm geht das ganze auch ohne threads ?



  • 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 ^^)



  • ratemal warum ich das mit den threads vorgeschlagen habe

    Schau dir mal das recv an, es könnte funktionieren wenn du erst ein peek mit recv machst und erst wenn Daten da sind ein recv mit auslesen der Daten

    MSG_PEEK Peeks at the incoming data. The data is copied into the buffer but is not removed from the input queue. The function then returns the number of bytes currently pending to receive. 
    
    MSG_OOB Processes OOB data. (See section DECnet Out-of-band data for a discussion of this topic.)
    

    Ein Hoch auf die Handbücher / MSDN



  • PAD schrieb:

    ratemal warum ich das mit den threads vorgeschlagen habe

    geht auch ohne. musser halt kbhit bemühen. ist zwar nicht ansi-c, aber threads sind's ja auch nicht.



  • Aber ist so eine polling Lösung sinnvoll.

    Und so schwer sind threads auch nicht.
    Mit threads kann man die 3 Aufgabe auch schön modulrisieren



  • PAD schrieb:

    Aber ist so eine polling Lösung sinnvoll.

    manchmal ja. gerade wenn man keine erfahrung mit threads hat kann man sich mit der synchronisation ganz schön rumärgern. ohne threads ist alles schön deterministisch, wie man's kennt. keine komischen race conditions die kaum zu debuggen sind.



  • mich würde auch interessieren wie man so etwas über select lösen kann
    steh nämlich vor genau dem gleichen problem

    man müsste ja nur dieses kbhit() ins select bringen



  • sorry, aber den thread hast du gelesen oder? sonst haettest du schon die loesung gesehen und die frage nicht gestellt.


Anmelden zum Antworten