Home > Net >  How to realize the Socket every once in a while to send the request until receive the corresponding
How to realize the Socket every once in a while to send the request until receive the corresponding

Time:10-10

Below as my current implementation methods:
 public async Task StartDownloadRequestAsync (StartDownloadMsg MSG, int requestCount, TimeSpan interval) 
{
Var data=https://bbs.csdn.net/topics/MessageConverter.Serialize (MSG);
Var response=await the Request (MSG) Header) MessageType, data, requestCount, interval);
Return MessageConverter. Deserialize (response);
}

Request:
 private async Task{
ValidRequest (type);

_cts=new CancellationTokenSource ();

Try
{
For (int count=0; The count & lt; RequestCount; Count++)
{
Send (MSG);
Await Task. Delay (interval, _cts Token);
}
}
The catch (OperationCanceledException)
{
TaskCompletionSourceTask. SetResult (_response);
Return await task. A task;
}
The finally
{
_isRequesting=false;
_response=null;
}

Throw new RequestTimeoutException ();
}


Receive a callback:
 private void ReceiveCallback (IAsyncResult async) 
{
The Socket Socket=async. AsyncState as Socket;
Int length=socket. EndReceive (async);

_buffer. Write (_received, 0, length);
_buffer. Seek (- length, SeekOrigin. End);

While (_buffer) Length - _buffer) Position & gt;=CanFrameLength)
{
Byte [] package=new byte [CanFrameLength];
_buffer. Read (package, 0, CanFrameLength);

Var type=(MessageType) package [TypeOffset];
The switch (type)
{
Case MessageType. StartDownloadResponse:
Case MessageType. DemandSectionResponseTwo:
Case MessageType.Com binePackageResponse:
Case MessageType.Com binePackageCompletedResponse:
Case MessageType. ProgramCheckoutResponse:
Case MessageType. ResetImmeiateResponse:
If (_isRequesting & amp; & Type==_waitResponseType)//is asking and the type of message types for response to
{
_response=package;
_cts. Cancel ();//direct request task
}
break;
Case MessageType. HeartbeatResponse:
_lastHeartbeat + +;
break;
Default:
break;
}
}

Socket. BeginReceive (_received, 0, _received. Length, SocketFlags. None, ReceiveCallback, socket);
}


Another way I can think of is every request to open a timer timing to send request, receive a callback after receive the specified response to stop the timer and inform requestor by events, the timer reaches the specified number haven't stop throwing timeout exception, this approach can not directly in the request function returns responses inside, use rise more troublesome,
As well as use WaitHandle to synchronization, request function inside loop to send to:
 for (int count=0; The count & lt; RequestCount; Count++) 
{
Send (MSG);
If (resetEvent. WaitOne (interval))
{
Return _response;
}
}

After receiving the specified response resetEvent. Set (), the way back to the threads blocked requests

Don't know if you have more elegant

CodePudding user response:

I also write something similar,
I am such processing
 
The class FunctionRquestData
{
Private Stopwatch sw=new Stopwatch ();
Public class packagedata
{
FunctionRquestData f;
Public Dictionary ();
Public void addreceivedata (int n, byte [] d)
{
if (! Data. Either ContainsKey (n))
{
Data. The Add (n, d);
F.f inished=false;
F. heckdone ();
F.s w.R estart ();
}
}
Public void addsenddata (int n, byte [] d)
{
//if (! Data. Either ContainsKey (n))
{
Data. The Add (n, d);
Udp. Send (d, d.L ength, f.i p);
}
}
Public int the count ()
{
Return the data. The Count;
}
Public void the clear ()
{
Data. The Clear ();
}
Public packagedata (FunctionRquestData F)
{
F=f;
}
}


Void checkdone ()
{

//determine whether complete

}
Void checktimeout ()
{
System. The Timers. The Timer dt=new System. Timers. The Timer () {Enabled=true, the Interval=100};

Dt. Elapsed +=delegate
{
if (! Finished)
{
If (sw) ElapsedMilliseconds & gt; 500)
{
Sw. Restart ();
//not finished processing
0.5 seconds}
}
If (sw) ElapsedMilliseconds & gt; 7000)
{

Senddata publishes the event. The clear ();

Dt. The Dispose ();//7 seconds after the delete
}
};

}
Public FunctionRquestData ()
{
Sw. Start ();
Checktimeout ();
}
}

CodePudding user response:

reference 1st floor m0_37646670 response:
I also write something similar,
I am such processing
 
The class FunctionRquestData
{
Private Stopwatch sw=new Stopwatch ();
Public class packagedata
{
FunctionRquestData f;
Public Dictionary ();
Public void addreceivedata (int n, byte [] d)
{
if (! Data. Either ContainsKey (n))
{
Data. The Add (n, d);
F.f inished=false;
F. heckdone ();
F.s w.R estart ();
}
}
Public void addsenddata (int n, byte [] d)
{
nullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnull
  •  Tags:  
  • C#
  • Related