473,405 Members | 2,287 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,405 software developers and data experts.

Socket.Receive blocks sometimes on localhost

I have a Windows Service application that acts as if it's an SMTP server.
Outlook connects to this service, which is always running on the localhost.
This works fine most of the time.
However, sometimes it will no longer receive anything from Outlook.
Socket.Receive would block indefinitely (actually, Socket.Poll times out,
because that's what I'm using). Outlook sends it, because when I'm stepping
through the code with the debugger, everything works.

Although this happens rarely, there is one situation where this always
happens: when Outlook has more than one message to send in a single
send/receive action, it will always block after the second MAIL command. An
example SMTP transcript:
220 localhost welcomes you to SignalMailSMTP
EHLO qualityweb
250 OK
MAIL FROM: <se****@signalmailsmtp.com>
250 Mail from se****@signalmailsmtp.com accepted
RCPT TO: <re******@signalmailsmtp.com>
250 Recipient re******@signalmailsmtp.com accepted
DATA
354 Start mail input; end with <CRLF>.<CRLF>
From: "SignalMail" <se****@signalmailsmtp.com>
To: <re******@signalmailsmtp.com>
Subject: AEX Enter Long alert
Date: Sat, 27 Sep 2003 14:03:28 +0200
Message-ID: <000701c384ef$5d1ae640$9dfc3850@qualityweb>
MIME-Version: 1.0
Content-Type: text/plain;
charset="us-ascii"
Content-Transfer-Encoding: 7bit
X-Priority: 3 (Normal)
X-MSMail-Priority: Normal
X-Mailer: Microsoft Outlook, Build 10.0.4510
X-MIMEOLE: Produced By Microsoft MimeOLE V6.00.2800.1165
Importance: Normal

..
250 OK
MAIL FROM: <se****@signalmailsmtp.com>
250 Mail from se****@signalmailsmtp.com accepted

The RCPT is never received. This has been reproduced on three separate
computers. Also, if you (or Outlook itself) retry too fast after this
failure, it will again fail, again at the RCPT command.

Now I can solve this by adding a delay (Thread.Sleep) but that's a highly
undesirable solution, as the exact delay value to make it work probably
depends on the speed of the computer it's running on. Also, it's a bit of a
hack.

Now I'm fresh out of ideas. It seems the message gets lost on the localhost
interface, but the question is, what can I do about it?
The code I'm using to receive:
Do
If mConnected.Poll(5000000, SelectMode.SelectRead) Then
BytesReceived = mConnected.Receive(Buffer)
Message &= Text.Encoding.ASCII.GetString(Buffer, 0, BytesReceived)
Else
mLogTransscript.Append("A timeout has occurred.")
mLogTransscript.Append(Environment.NewLine)
If Not mTransscript Is Nothing Then
mTransscript.WriteLine("A timeout has occurred.")
End If
mLogError = True
mState = SmtpState.Quit
Return Nothing
End If
Loop While Message.IndexOf(endSequence) = -1

Hopefully someone here can help.

--
Sven Groot

Nov 20 '05 #1
3 4120
Have you tried Thread.Sleep(0)? That way you don't have to calculate the
exact time to sleep for different machines.

"Sven Groot" <sv*******@gmx.net> wrote in message
news:#P**************@TK2MSFTNGP11.phx.gbl...
I have a Windows Service application that acts as if it's an SMTP server.
Outlook connects to this service, which is always running on the localhost. This works fine most of the time.
However, sometimes it will no longer receive anything from Outlook.
Socket.Receive would block indefinitely (actually, Socket.Poll times out,
because that's what I'm using). Outlook sends it, because when I'm stepping through the code with the debugger, everything works.

Although this happens rarely, there is one situation where this always
happens: when Outlook has more than one message to send in a single
send/receive action, it will always block after the second MAIL command. An example SMTP transcript:
220 localhost welcomes you to SignalMailSMTP
EHLO qualityweb
250 OK
MAIL FROM: <se****@signalmailsmtp.com>
250 Mail from se****@signalmailsmtp.com accepted
RCPT TO: <re******@signalmailsmtp.com>
250 Recipient re******@signalmailsmtp.com accepted
DATA
354 Start mail input; end with <CRLF>.<CRLF>
From: "SignalMail" <se****@signalmailsmtp.com>
To: <re******@signalmailsmtp.com>
Subject: AEX Enter Long alert
Date: Sat, 27 Sep 2003 14:03:28 +0200
Message-ID: <000701c384ef$5d1ae640$9dfc3850@qualityweb>
MIME-Version: 1.0
Content-Type: text/plain;
charset="us-ascii"
Content-Transfer-Encoding: 7bit
X-Priority: 3 (Normal)
X-MSMail-Priority: Normal
X-Mailer: Microsoft Outlook, Build 10.0.4510
X-MIMEOLE: Produced By Microsoft MimeOLE V6.00.2800.1165
Importance: Normal

.
250 OK
MAIL FROM: <se****@signalmailsmtp.com>
250 Mail from se****@signalmailsmtp.com accepted

The RCPT is never received. This has been reproduced on three separate
computers. Also, if you (or Outlook itself) retry too fast after this
failure, it will again fail, again at the RCPT command.

Now I can solve this by adding a delay (Thread.Sleep) but that's a highly
undesirable solution, as the exact delay value to make it work probably
depends on the speed of the computer it's running on. Also, it's a bit of a hack.

Now I'm fresh out of ideas. It seems the message gets lost on the localhost interface, but the question is, what can I do about it?
The code I'm using to receive:
Do
If mConnected.Poll(5000000, SelectMode.SelectRead) Then
BytesReceived = mConnected.Receive(Buffer)
Message &= Text.Encoding.ASCII.GetString(Buffer, 0, BytesReceived)
Else
mLogTransscript.Append("A timeout has occurred.")
mLogTransscript.Append(Environment.NewLine)
If Not mTransscript Is Nothing Then
mTransscript.WriteLine("A timeout has occurred.")
End If
mLogError = True
mState = SmtpState.Quit
Return Nothing
End If
Loop While Message.IndexOf(endSequence) = -1

Hopefully someone here can help.

--
Sven Groot

Nov 20 '05 #2
Hi,

Suggestions:
1)don't store message to string, stote it as byte[] in to MemoryStream.

2) Loop While Message.IndexOf(endSequence) = -1, if message gets
bigger(contains attachment) this code kill your computer.
Store only last 5 bytes (<CRLF>.<CRLF>), which can be used to check for data
terminator.

3) put in while loop Thread.Sleep(50) or other wise this code eats 100% of
your cpu.
(Sleep only if data not available to read)

4) Use Socket.Available to see if data must be readed or just wait to arrive
(Thread.Sleep(50) )
For complete solution see www.lumisoft.ee mail server project.
It provides SMTP/POP3/IMAP working server code.

This code is easy to follow, it's well commented, but it's in c#.

I'm sure you can find many good solutions,ideas from there or even may use
whole project.
(There isn't any need to invent bicycle, because of it already exists)

If you have some SMTP specific questions, you may email iv**@lumisoft.ee.
"Sven Groot" <sv*******@gmx.net> wrote in message
news:%2****************@TK2MSFTNGP11.phx.gbl...
I have a Windows Service application that acts as if it's an SMTP server.
Outlook connects to this service, which is always running on the localhost. This works fine most of the time.
However, sometimes it will no longer receive anything from Outlook.
Socket.Receive would block indefinitely (actually, Socket.Poll times out,
because that's what I'm using). Outlook sends it, because when I'm stepping through the code with the debugger, everything works.

Although this happens rarely, there is one situation where this always
happens: when Outlook has more than one message to send in a single
send/receive action, it will always block after the second MAIL command. An example SMTP transcript:
220 localhost welcomes you to SignalMailSMTP
EHLO qualityweb
250 OK
MAIL FROM: <se****@signalmailsmtp.com>
250 Mail from se****@signalmailsmtp.com accepted
RCPT TO: <re******@signalmailsmtp.com>
250 Recipient re******@signalmailsmtp.com accepted
DATA
354 Start mail input; end with <CRLF>.<CRLF>
From: "SignalMail" <se****@signalmailsmtp.com>
To: <re******@signalmailsmtp.com>
Subject: AEX Enter Long alert
Date: Sat, 27 Sep 2003 14:03:28 +0200
Message-ID: <000701c384ef$5d1ae640$9dfc3850@qualityweb>
MIME-Version: 1.0
Content-Type: text/plain;
charset="us-ascii"
Content-Transfer-Encoding: 7bit
X-Priority: 3 (Normal)
X-MSMail-Priority: Normal
X-Mailer: Microsoft Outlook, Build 10.0.4510
X-MIMEOLE: Produced By Microsoft MimeOLE V6.00.2800.1165
Importance: Normal

.
250 OK
MAIL FROM: <se****@signalmailsmtp.com>
250 Mail from se****@signalmailsmtp.com accepted

The RCPT is never received. This has been reproduced on three separate
computers. Also, if you (or Outlook itself) retry too fast after this
failure, it will again fail, again at the RCPT command.

Now I can solve this by adding a delay (Thread.Sleep) but that's a highly
undesirable solution, as the exact delay value to make it work probably
depends on the speed of the computer it's running on. Also, it's a bit of a hack.

Now I'm fresh out of ideas. It seems the message gets lost on the localhost interface, but the question is, what can I do about it?
The code I'm using to receive:
Do
If mConnected.Poll(5000000, SelectMode.SelectRead) Then
BytesReceived = mConnected.Receive(Buffer)
Message &= Text.Encoding.ASCII.GetString(Buffer, 0, BytesReceived)
Else
mLogTransscript.Append("A timeout has occurred.")
mLogTransscript.Append(Environment.NewLine)
If Not mTransscript Is Nothing Then
mTransscript.WriteLine("A timeout has occurred.")
End If
mLogError = True
mState = SmtpState.Quit
Return Nothing
End If
Loop While Message.IndexOf(endSequence) = -1

Hopefully someone here can help.

--
Sven Groot

Nov 20 '05 #3
"Sven Groot" <sv*******@gmx.net> wrote
If mConnected.Poll(5000000, SelectMode.SelectRead) Then
BytesReceived = mConnected.Receive(Buffer)
Message &= Text.Encoding.ASCII.GetString(Buffer, 0, BytesReceived)
Else


Why do you use Poll with such a huge number? You can better call Receive
directly without using Poll. Receive will block until data is available.

BytesReceived = mConnected.Receive(Buffer)
If Buffer > 0 Then
Message &= Text.Encoding.ASCII.GetString(Buffer, 0, BytesReceived)
Else
' other side closed connection, or timeout
End If

I also agree with Ivar about the checking of only the last few bytes instead
of using IndexOf on the entire message.
You may also want to consider using a StringBuilder instance instead of
concatenating strings. This will greatly enhance the performance.

Regards,
Pieter Philippaerts
Managed SSL/TLS: http://www.mentalis.org/go.php?sl
Nov 20 '05 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

12
by: Sven Groot | last post by:
I have a Windows Service application that acts as if it's an SMTP server. Outlook connects to this service, which is always running on the localhost. This works fine most of the time. However,...
1
by: mjcast | last post by:
I have been working on an ActiveX control in C#. It is packaged in a Windows Control library and the code is in a user control. The control is used as an automation receiver that is used to update a...
5
by: Terry | last post by:
It's my understanding of UDP sockets that if there is a thread blocked on a "recvFrom()" call and other thread sends a UDP packet to some address, that if the machine on the other end isn't up,...
4
by: Pete Davis | last post by:
I've written an async socket server app and I'm having an issue with the EndReceive() call. My begin receive call is: sockState.RemoteSocket.BeginReceive(sockState.ReceiveBuffer, 0,...
2
by: Droopy | last post by:
Hi, I try to implement a reusable socket class to send and receive data. It seems to work but I have 2 problems : 1) I rely on Socket.Available to detect that the connection is closed (no...
1
by: Laura T. | last post by:
Hi, I've this kind a program, using sockets to communicate with the clients. One of the clients can be a web browser (like IE). When using IE as a client, the transmission blocks completely, and...
2
by: Nuno Magalhaes | last post by:
I've got a simple problem I guess. How do I know when a connection is terminated without losing any data? I do something like the code below, but sometimes between socket.Receive and socket.Send...
6
by: Pat B | last post by:
Hi, I'm writing my own implementation of the Gnutella P2P protocol using C#. I have implemented it using BeginReceive and EndReceive calls so as not to block when waiting for data from the...
0
by: petr.poupa | last post by:
Hello, I am beginner but so I need help. I have small script for receive data from port 3883, but it print only once. import socket HOST = 'localhost' PORT = 3883 s =...
1
by: Jean-Paul Calderone | last post by:
On Mon, 12 May 2008 08:34:07 -0700 (PDT), petr.poupa@gmail.com wrote: You cannot reconnect a socket. You need to create a new one for each connection. It's also almost certainly the case that...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.