Běh dvou příkazů ve stejnou chvíli (recv() a std::cin) – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Běh dvou příkazů ve stejnou chvíli (recv() a std::cin) – C / C++ – Fórum – Programujte.comBěh dvou příkazů ve stejnou chvíli (recv() a std::cin) – C / C++ – Fórum – Programujte.com

 

Jan Frýda
~ Anonymní uživatel
2 příspěvky
30. 6. 2016   #1
-
0
-

Ahoj, potřeboval bych s něčím poradit.

Učím se s knihovnou winsock. Zkoušel jsem udělat chat, s tím že si prostě budou moct dva a více lidí mezi sebou moct psát. Problém je v tom, že nevim jak udělat, aby se zároveň mohly přijímat a zobrazovat zprávy, ale uživatel mohl stále psát nějakou zprávu.

když udělám něco jako je toto:

char Zprava[256];
SOCKET Connection = socket(AF_INET, SOCK_STREAM, NULL)
connect(Connection, (SOCKADDR*)&addr, sizeofaddr)

while(1)
{
        cin >> Zprava;
        send(Connection, Zprava, sizeof(Zprava),NULL);
        recv(Connection, Zprava, sizeof(Zprava),NULL);
        cout << Zprava << "\n";

}

tak jakmile dojdu k cin >> Zprava, tak se nebudou uživateli zobrazovat zprávy dokud nějakou nepošle. Problém nastává i ve chvíli, když chce jeden uživatel napsat 2x zprávu po sobě, protože jakmile něco napíše, musí počkat než mu přijde další zpráva, aby mohl zase psát.

Nahlásit jako SPAM
IP: 85.119.94.–
Jan Frýda
~ Anonymní uživatel
2 příspěvky
30. 6. 2016   #2
-
0
-

A nikde nemohu najít něco odkud se dá něco o této knihovně něco dozvědět. Nevíte někdo o nějakém návodu nebo něco? Hodil by se nějakej odkaz. Díky

Nahlásit jako SPAM
IP: 85.119.94.–
q
~ Anonymní uživatel
219 příspěvků
30. 6. 2016   #3
-
0
-

Můžeš socket přepnout do neblokujícího režimu -- recv nebude čekat na data, ale vrátí jen to, co je k dispozici (třeba i nic) = ioctlsocket FIONBIO -- nebo před voláním recv otestovat, jestli je něco k načtení = select apod.

Nevím, co a jak jsi hledal, že jsi nic nenašel. Každopádně kompletní dokumentace je jako vždy v MSDN - Windows Sockets 2.

Nahlásit jako SPAM
IP: 213.211.51.–
Nahlásit jako SPAM
IP: 195.178.67.–
kocourOggy0
Newbie
2. 7. 2016   #5
-
0
-

Tohle ale resi problem jen castecne. Jakmile se program dostane k cin >> Zprava, tak program ceka na vstup (stisk enteru) a do te doby neprijima zpravy, jak uz vlastne Jan napsal. Jestli existuje nejaky standartni postup jak zachytavat vstup okamzite (bez cekani na enter) netusim. Nejjednodussi by bylo pouzit nejakou knihovnu, ktera ti poskytne alternativu za cin. Ja znam treba knihovnu ncurses (myslim, ze se da pouzit jak na Windows tak i Linuxu) nebo conio (pro Windows). V ncurses ta dulezita funkce bude getch(), ktera zachyti znak a pomoci podminek uz si budes kontrolovat jestli chces zpravu odeslat anebo ne a co vic getch() ti nezastavi beh smycky while, kdyz pouzijes volani nodelay(), takze budes moct zaroven psat i prijimat...
Priklad:

#include <ncurses.h>
#include <string>

#define ESC 27

using namespace std;
 
int main()
{
  string msg;               // retezec pro ukladani jednotlivych znaku
  int c;                    // do c budeme ukladat jednotlive stisky tlacitka
  int currentLine = 0;      //
  int curRow;
  int curCol;
  int row,col;              // pocet radku a sloupcu  
  initscr();				        // spusti okno ncurses
  noecho();                 
  cbreak();
  nodelay(stdscr, TRUE);    // getch() nebude blokovat program kdyz nic nestiskneme
  getmaxyx(stdscr,row,col); // zjisti pocet radku a sloupcu konzole  
  curRow = row - 1;
  curCol = 0;
  move(curRow -1, curCol);          // posun kurzor na posledni radek
  refresh();                // aktualizuj okno (jinak se kurzor neposune)
  while (1)
  {
   	c = getch();            // odchyt tlacitko, fce getch() neceka na ENTER!!!
   	move(curRow, 0);
   	refresh();  
   	if (c == '\n')          // kdyz stisknu ENTER ukaz mi zpravu v historii konverzace
   	{
   	  mvprintw(currentLine, 0, "You Entered: %s", msg.c_str());
   	  ++currentLine;
   	  msg.clear();
   	  move(curRow -1, 0);
   	  refresh();  
   	  curCol = 0;
   	}
   	
   	else if (c > 31 && c < 127) // c musi byt znak abecedy, mezera apod (viz ascii)
   	{
   	  msg.push_back( (char)c );
  	  move(curRow, curCol);
  	  addch((char)c);           // zobraz stisknuty znak
  	  refresh();   
  	  ++curCol;
   	}	  
   	else if (c == ESC)          // ESC opusti smycku
   	{
   	  break;
   	}
  }	
  
  endwin();                 // ukonci okno ncurses
  return 0;
}
Nahlásit jako SPAM
IP: 78.45.112.–
Věčný začátečník nejen v Pythonu.
4. 7. 2016   #6
-
0
-

Standartně se práce se sokety nebo periferiemi dělá v samostatném vlákně a pak čekání na cin v hlavním vlákně ničemu nebrání.

Edit: možná se mýlím, ale i u standartních proudů lze zjistit kolik znaků je na vstupu.

hu

Nahlásit jako SPAM
IP: 195.178.67.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 41 hostů

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý