|
Hi there,
I've been trying to use multithreading on a socket but without success. Here is what I want to do: I have a socket that is shared by two threads. One of them is continuously blocked on a Receive and the other one sends bytes (asynchronously) through the same socket. However, I can't do both things at the same time. If I have the first thread blocked on a Receive, when I use the other thread to send bytes I get an exception in the former thread saying something that an existing connection was forced to close by remote host...
Any help?
Thanks,
Spulit
|
|
|
|
|
Spulit wrote: and the other one sends bytes (asynchronously)
Post that part of the code.
led mike
|
|
|
|
|
Here is a simplified version ("buffer" is protected by a mutex). The receiving thread is a BackgroundWorker (readSocket method) which is fired over and over again until the thread is cancelled.
SocketRW::SocketRW(unsigned short int port_)
{
Port = port_;
socket = gcnew Socket(AddressFamily::InterNetwork,SocketType::Dgram,ProtocolType::Udp);
socket->Bind(gcnew IPEndPoint(IPAddress::Any, Port));
buffer = gcnew array<unsigned char="">(512);
worker = gcnew BackgroundWorker;
worker->WorkerSupportsCancellation = true;
worker->DoWork += gcnew DoWorkEventHandler(&(SocketRW::readSocket));
worker->RunWorkerCompleted += gcnew RunWorkerCompletedEventHandler(&(SocketRW::fireMsg));
}
void SocketRW::readSocket(Object^ sender, DoWorkEventArgs^ e)
{
int bytesrec;
try{
Array::Clear(buffer, 0, buffer->Length);
bytesrec = socket->Receive(buffer);
}
catch(Exception ^e)
{
// Whenever the other thread sends bytes through this socket, the Receive method above throws an System.Net.Sockets.SocketException with the message I posted above.
}
e->Result = bytesrec;
}
void SocketRW::fireMsg(Object^ sender, RunWorkerCompletedEventArgs^ e)
{
// do stuff with the message in "buffer"
// Need this in order to update the GUI with the correct thread
if (!e->Cancelled)
worker->RunWorkerAsync();
}
|
|
|
|
|
You have identified your problem. If you intend to use a single buffer for sending and receiving, then your receive must not block. Instead of causing the receive thread to not block, use separate buffers for reading and writing. Then you won't need a mutex to control access to the buffer.
Phil
|
|
|
|
|
Hi pbraun,
Thanks for your reply, but of course I'm not using the same buffer for sending and receiving. I just protect the receiving buffer because it is used in the BackgroundWorker method (for the Socket::Receive() method) and in the RunWorkerCompletedEventHandler (which runs in the main thread context, the same thread that is used to send bytes through the socket).
Thanks,
Spulit
|
|
|
|
|
Yeah, I have never really done any UDP but I don't think it works like a Stream socket. Take a look at this article[^] which uses two UdpClient objects, one for sending and one for receiving.
led mike
|
|
|
|
|
Hello,
I have a multiple instances that bind and listen to the same UDP (with same IP and Port #).
Is it possible to do that?
I set my UDP socket to REUSEADDRESS, but it seems only 1 instance receives the data. The rest are not.
Please help me,
Thanks,
nsutanto
|
|
|
|
|
We are presently upgrading from .Net 2003 to 2005. We have an application that invokes an FTP client asynchronously via a process component, redirecting standard output to a log file. In .Net 2003, all of standard output is redirected to the log file, however, in .Net 2005, only the commands we are passing to the ftp client are redirected to the log file. All of the FTP responses ie: “1000 bytes transmitted in 2 seconds”, etc. are not redirected to the log file.
The relevant lines of code are as follows:
Dim myProcess As New Process
myProcess.StartInfo.FileName = "FTP.exe"
myProcess.StartInfo.UseShellExecute = False
myProcess.StartInfo.RedirectStandardOutput = True
myProcess.Start()
Dim myStreamReader As StreamReader = myProcess.StandardOutput
Dim myStreamWriter As StreamWriter = File.AppendText(“myLog.txt”)
While Not sLine Is Nothing
myStreamWriter.WriteLine(sLine)
sLine = myStreamReader.ReadLine()
End While
myProcess.WaitForExit()
Does anyone know if changes were made with regard to the redirect of standard output for process components?
Thanks in advance for your replies.
|
|
|
|
|
Hi,
I have two projects in my project explorer which I would like to debug.The main project calls the other one with
Process.Start(new ProcessStartInfo(SubExe, Variables)
But when I set a breakpiont in my sub project and start the debugger I get the message
The breakpoint will not currently be hit. No symbols have been loaded for this document
I have alredy set the configuration to debug, deleted bin and obj folders with pdb and exe folders and rebuilt both projects. I would be very grateful for any suggestions
|
|
|
|
|
Close all instances of VisualStudio. Goto VSWebCache folder. Empty it. Now open the solution and Rebuild.
Sometimes the cache goes out of sync.
|
|
|
|
|
Thanks for the reply. But it doesn't work either
|
|
|
|
|
Perhaps it would be better to just start the process you want to debug and then use the debug process to hook into the thing you want to debug. If one of the projects you are trying to debug is a windows service, using the debug processes is a good way to debug.
Hope that helps.
Ben
|
|
|
|
|
Thats a good idea. The process I want to debug is expecting argumets from the caller procedure, but I think I can work around and this will work. Many Thaks.
|
|
|
|
|
It could also be that you set a breakpoint on a section of code that will never called. The debugger can figure this out when you start your app.
Dave Kreskowiak
Microsoft MVP - Visual Basic
|
|
|
|
|
I place the breakpoint on a MessageBox which is displayed when I start the application but the breakpoint itself wont be hit
|
|
|
|
|
Configuration (Release) Mode?
|
|
|
|
|
The way described by Ben is the solution to my problem. It works fine. Thanks for your help
|
|
|
|
|
I have seen a webconfig entry for .NET Framework 3.0 where it seems to give an option of file Upload like MEMORY or STREAM to disk. I could'nt find out now immediately.
Can somebody help me out with this?
|
|
|
|
|
Hello,
I have 2 instances of server.
Both instances create UDP socket listening for incoming messages.
It seems that only 1 instace of my server can listen to the messages, the other seems to see that the UDP socket is not available when it suppose to receive.
Below are portion of my code:
Socket udpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); udpSocket.SetSocketOption(SocketOptionLevel.Socket ,SocketOptionName.ReceiveBuffer,BufferCapacity);
udpSocket.SetSocketOption(SocketOptionLevel.Socket , SocketOptionName.ReuseAddress, 1);
int servicePort = (int)transport.Properties["port"];
System.Net.IPEndPoint localEndPoint = new System.Net.IPEndPoint(System.Net.IPAddress.Any, servicePort);
IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
EndPoint tempRemoteEndPoint = (EndPoint)sender;
udpSocket.Bind(localEndPoint);
while (keepAlive)
{
fetchSignal.WaitOne();
//This call is made to yield processor resources, Remote Client doesn't
//consume 100% of the CPU.
Thread.Sleep(1);
while (keepFetching && (udpSocket.Available > 0)) //only if data is available..
{
.......
}
}
NOTE: The 2nd instance see that the udpSocket.Available is 0. While the 1st instance can see that the udpSocket is greater than 0.
|
|
|
|
|
In a multithreading application I was wondering if I need to worry about 2 seperate threads overwriting each other's local variables.
In other words if 2 seperate threads called the same function at the same time would the compiled program in essence create 2 sets of local variables, one for each thread, or is there a risk that they could overwrite each others data?
Thanks for your help,
Mike
|
|
|
|
|
MikeMarq wrote: if 2 seperate threads called the same function at the same time would the compiled program in essence create 2 sets of local variables, one for each thread
Yes.
For more on this, check out a discussion[^] I had with someone on the C# message board.
|
|
|
|
|
Cool, thanks for the help.
|
|
|
|
|
Read about synclock and monitor. They provide a mechanism that locks an object and blocks other threads from accessing it except the thread that created the lock. When the lock is released the blocked threads are allowed similar lock and access.
|
|
|
|
|
I’m writing a C# DLL that executes a web browser. I have to grab a static image when the browser is done updating. So I wrote the following code.
public string SaveImageToFile()
{
int done = 0;
String file = "";
while (done < 20)
{
if (((webbrowser1.IsBusy == false) && (webbrowser1.ReadyState == WebBrowserReadyState.Complete)) || (done == 19))
{
Bitmap docImage = new Bitmap(webbrowser1.Width, webbrowser1.Height);
webbrowser1.DrawToBitmap(docImage, new Rectangle(webbrowser1.Location.X,
webbrowser1.Location.Y, webbrowser1.Width, webbrowser1.Height));
file = "C:\\Rumper\\tempA" + num + ".bmp";
docImage.Save(file, System.Drawing.Imaging.ImageFormat.Bmp);
++num;
done = 20;
}
else
{
System.Threading.Thread.Sleep(100);
Application.DoEvents();
++done;
}
}
return file;
}
However when I call SaveImageToFile from my MFC application, I get a stackoverflow. If I comment out the DoEvents. No stack overflow and no image.
I need to replace DoEvents, but I’m not sure what would be a better method.
Thanks
Programmer
Glenn Earl Graham
Austin, TX
|
|
|
|
|
Is this method called from within an event handler? If so, calling DoEvents may be refiring the same event and calling your code again, and again while you are still inside of the While loop. I would suggest removing the event handler at the begining to the SaveImageToFile method, then adding the handler at the end. This can also be done within the Event handler method as well.
I have had way to many headaches for this problem to hit me again, and 99% of the time, it's because the event is being fired before your code completes.
Hope this helps,
Scott Page
"Some people spend an entire lifetime wondering if they made a difference. The Marines don't have that problem."
( President Ronald Reagan)
|
|
|
|