Builder.cz - Informacni server o programovani

Odběr fotomagazínu

Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!

 

Zadejte Vaši e-mailovou adresu:

Kamarád fotí rád?

Přihlas ho k odběru fotomagazínu!

 

Zadejte e-mailovou adresu kamaráda:

Prijem dat - vlakno

Seznam témat     Nová odpověď

Přihlásit se     Registrace     Zapomenuté heslo

Re: Prijem dat - vlakno

Autor: spiritus

10:50:59 26.07.2011

Generovat UDP tok na embedded zarizeni je jednoduche. Zvlast pokud je vytvarime primo pomoci hardwaru, bez pouziti TCP stacku.

Pripada mi, ze vypadky nastavaji prave az na prijimaci strane v PC (na rychlejsim PC funguje, na pomalejsim ne). Takze zrejmmne delam prijem spatne. Rad bych zpracovaval tok kolem 100mbit/s. Nepredpoklada se provoz pres nejak velkou sit (max. 1switch), tekze prehazeni paketu pri transportu siti nehrozi.

Citovat příspěvek

 

Re: Prijem dat - vlakno

Autor: Mi.Chal

9:05:04 26.07.2011

pokud ti vadi vypadky, tak proc pouzivas UDP?

Citovat příspěvek

 

Re: Prijem dat - vlakno

Autor: spiritus

22:55:00 25.07.2011

Provedl jsem par pokusu kolem prijmu UDP dat.
Zlepseni prineslo, pokud jsem v aplikace pouzil pro synchronizaci prijimaciho vlakna a halvniho formu fce. PostMessage() namisto Synchronize a predaval pres ni naprijimana data. Vysvetluji si to tim, ze Synchronize() ceka na vstup fronty zprav halvniho okna, kdezto PostMessage okamzite zaradi pozadavek do fronty a neblokuje tak volajici vlakno.
Vypadky v prijmu se zlepsily (uz lze klikat do hlavniho okna nebo okno pretahovat). nicmene nahodne vypadky prijimanych UDP paketu pretrvavaly (na 1000paketu o delce 1400B se objevily cca. 1-2 chyby - tok 15Mb/s ). Zjednodusil jsem tedy prijimaci vlakno az do podoby konzolove apliakace, ktera opet pouze prijima pakety a kontroluje jejich delku a poradi. Vypis programu je prilozen.
Zajimave je, ze tento konzolovy program na mem NB (2jadra 1.8GHz winXP) stale vykazuje chyby v prijmu paketu (1000paketu 1chyba), pokud ho nahraji na vykonejsi desktop (6jader 2GHz win7) vse bezelo po dobu 1hodiny bez vypadku. Pochybuji, ze to znamena, ze by muj NB nebyl schopen prijimat UDP tok 15Mb/s, spise je nekde v kodu nejake slabe misto nebo nedomyslenost? Mozna najit jiny zpusob prijmu udp dat?
Prijimaci kod uz nemuze byt jednodussi. V teto podobe nic neuklada, pouze kontroluje navaznosti paketu a pokud dojde k chybe, zvysuje pocitadlo chyb.
Umi nekdo vysvetlit, proc i takto jednoduchy kod je v prijmu UDP dat nesolehlivy na "pomalejsim" PC?

//---------------------------------------------------------------------------

#include
#pragma hdrstop
#include "stdio.h"
#include "winsock2.h"
//---------------------------------------------------------------------------

#pragma argsused

typedef union {unsigned short ss;unsigned char c[2];} MUSIGNEDSHORT;

void FFT_ReceiveProcess(unsigned char *buff,int buff_length);

int SpectrumError =0;
int SpectrumValid = 0;
int CountOk = 0;

bool BuffInProgress = false;
int main(int argc, char* argv[])
{

bool stay_run = true;
int from_len;
int port = 3007;
SOCKET sd = 0;
struct sockaddr_in from;
struct sockaddr BindError, FromAddr;
int nBindErr,nReadErr,nSocketErr;
char buff[8192];


while( stay_run ) {
while( ! port ) {
//Suspend();
printf ("Suspend()\n");
if( ! stay_run ) {
if( port || sd > 0 ) {
if( sd > 0 ) sd = closesocket( sd );
port = 0;
}

break;
}
continue;
}

// create UDP socket
if( ! sd ) {
//----------------------
// Initialize Winsock
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);

sd = socket(AF_INET, SOCK_DGRAM, 0);
if( sd > 0 ) {
memset( &from, 0, sizeof( from ) );
memset (&FromAddr, 0, sizeof(FromAddr));
memset (&BindError, 0, sizeof(BindError));

from.sin_family = AF_INET;
from.sin_addr.s_addr = INADDR_ANY;
from.sin_port = htons( port );
nBindErr = bind( sd, (SOCKADDR *) &from, sizeof( from ) );
if( nBindErr ) {
nBindErr = WSAGetLastError();
printf ("Bind error &d\n",nBindErr);

}
}
}
if( sd == INVALID_SOCKET ) {
nSocketErr = WSAGetLastError();
nBindErr = 0;
printf ("ERROR Socket: %d\n",nSocketErr);
continue;
} else {
nSocketErr = 0;
from_len = sizeof( FromAddr );
}

// loop until we receive 0 bytes
int rcvlen = 1;
while (1) { //opravit > 0
// receiving is done here
int rcvlen = recvfrom(sd, buff, 1500, 0, &FromAddr, &from_len);
if (BuffInProgress) printf ("!!Buffer process error\n");
BuffInProgress = true; //test
if( rcvlen > 0 ) {
FFT_ReceiveProcess(buff,rcvlen);

}
else {

nReadErr = WSAGetLastError();
printf ("RECVFROM error: %d\n",nReadErr);
if( rcvlen == -1 && nReadErr == 10004 ) {
//port was closed
if( port ) {
printf ("port was closed\n");
break;
}
break;
}

break;
}
from.sin_port = htons( from.sin_port );

}
}

return 0;
}
//---------------------------------------------------------------------------

void FFT_ReceiveProcess(unsigned char *buff,int buff_length){
//Spravny prijem UDP dat
MUSIGNEDSHORT start, stop;
char Type;
static int StateSpectrum = 0;


if (buff_length==1048) {
//Only if packet has exact length
if ((buff[0]=='I') && (buff[1]=='J') && (buff[2]==126)) {

Type = buff[3]; /
start.c[0] = buff[4];
start.c[1] = buff[5]; //fill the start index
stop.c[0] = buff[6];
stop.c[1] = buff[7]; //fill the stop index

switch (StateSpectrum){
case 0:
case 1:
if ((start.ss==1024) && (stop.ss==1279) && (Type=='R' || Type=='I')){
BuffInProgress = false;
StateSpectrum++;

}
else{ StateSpectrum = 0;

}
break;

case 2:
case 3:
if ((start.ss==1280) && (stop.ss==1535) && (Type=='R' || Type=='I')) {
StateSpectrum++;
BuffInProgress = false;
}else{ StateSpectrum = 0;
SpectrumError++;

}
break;

case 4:
case 5:
if ((start.ss==1536) && (stop.ss==1791) && (Type=='R' || Type=='I') ) {
StateSpectrum++;
BuffInProgress = false;
}else{ StateSpectrum = 0;
SpectrumError++;

}
break;

case 6:
case 7:
if ((start.ss==1792) && (stop.ss==2047) && (Type=='R' || Type=='I')){
StateSpectrum++;
BuffInProgress = false;
}else { StateSpectrum = 0;
SpectrumError++;

}

break;

case 8:
case 9:
if ((start.ss==0) && (stop.ss==255) && (Type=='R' || Type=='I') ){
StateSpectrum++;
BuffInProgress = false;
}else{ StateSpectrum = 0;
SpectrumError++;

}
break;

case 10:
case 11:
if ((start.ss==256) && (stop.ss==511) && (Type=='R' || Type=='I') ){
StateSpectrum++;
BuffInProgress = false;
}else{ StateSpectrum = 0;
SpectrumError++;

}
break;

case 12:
case 13:
if ((start.ss==512) && (stop.ss==767) && (Type=='R' || Type=='I')) {
StateSpectrum++;
BuffInProgress = false;
}else{ StateSpectrum = 0;
SpectrumError++;

}
break;

case 14:
case 15:
if ((start.ss==768) && (stop.ss==1023) && (Type=='R' || Type=='I') ) {
spektrumRE_kompletni = 0xFF;
BuffInProgress = false;
if (Type=='I') {
//SendingThread->BufferUdpRe->AddN(SpektrumReTemp, 8192);
//SendingThread->BufferUdpIm->AddN(SpektrumImTemp, 8192);

//if (SendingThread->Suspended )
// SendingThread->Resume();
// count++;
// if (count >1) {

// count = 0;
//}

SpectrumValid++;

//Synchronize (&DataToForm);
if (CountOk++ == 500) {
CountOk = 0;
printf ("Valid spectrum: %d Error spectrum: %d\n",SpectrumValid, SpectrumError);
}
StateSpectrum = 0;
}else StateSpectrum++;
}
else {SpectrumError++;

}

break;

case 16:
StateSpectrum = 0;
SpectrumError++;
break;
}//switch


}else {
printf ("INVALID header!\n");
}
}else {
printf ("INVALID length!\n");
}
}
//---------------------------------------------------------------------------

Citovat příspěvek

 

Re: Prijem dat - vlakno

Autor: spiritus

9:15:00 23.07.2011

Pro jednoduchost jsem program zjednodusil. Prijimaci vlakno UDP dat ThreadUdpReceive pouze zkontroluje navaznost paketu (pakety obsahuji inkrementujici se poradova cisla).
I tak dochazi k vypadkum prave v okamziku, kdy uzivatel pracuje s hlavnim formem. Otazka z predchoziho emailu tedy trva, jak zajistit bezchybny prijem dat? Co vlasnte rusi prijimaci, nezavisle(podle me) vlkano kdyz se klika do hlavniho formu? Jak tomuto predejit?

dekuji VS

Citovat příspěvek

 

Prijem dat - vlakno

Autor: spiritus

17:04:23 22.07.2011

Po delsi dobe jsem se opet pustil do zpracovani prijmu UDP toku.
Mam vytvorene vlakno ThreadUdpReceive v nemz prijimam obsluhu udp dat:
while (1) {
int rcvlen = recvfrom(sd, buff, 1500, 0, &FromAddr, &from_len);
if( rcvlen > 0 ) {
FFT_ReceiveProcess(buff,rcvlen);

}
}

Funkce FFT_ReceiveProcess uklada buff do "vlaknove bezpecneho bufferu" synchronizovaneho pomoci criticalsection (metody enter a leave). Pokud funkce FFT_ReceiveProcess rozhodne, ze bylo vse naprijimano a vsechna prijata data jsou platna, vyvola vlakno Thread_Sync pomoci Resume.

Thread_Sync zpracuje predana data z "vlaknove bezpecneho bufferu" a pomoci synchronize preda pointery na nove vytvorene buffery hlavnimu formu, kde se zobrazuji.

void __fastcall Thread_Sync::Execute(){
int a =2;
static int count = 0;
while(1){
BufferUdpRe->GetN(8192,SpektrumReTemp);
BufferUdpIm->GetN(8192,SpektrumImTemp);

Synchronize (&DataToForm);

Suspend();
}
Potreboval bych zajistit bezpecny prijem UDP paketu (predpoklada se provoz pres 1 switch,takze vypadky v siti by nastavat nemely). Pokud napr. chytnu okno nebo klikam uvnitr hlavniho okna dochazi k vypadku prijmu paketu (tok UDP je cca. 10Mb/s). Jakym zpusobem lze zajistit vetsi spolehlivost prijmu UDP dat?

Citovat příspěvek

 

 

 

Přihlášení k mému účtu

Uživatelské jméno:

Heslo: