cancel
Showing results for 
Search instead for 
Did you mean: 

Problem reading all data from Synchronous Socket

Former Member
0 Kudos

Hi,

I have the task to implements an C# application which communicates with a SAP system via HTTP. My application should act as a HTTP Server to the SAP system. SAP sends documents (PDFs, Word-Docs, Tifs) through HTTP-Requests to my Server. Archive Link is SAP´s name for that HTTP interface.

Currently I am using synchronous sockets to process the communication. So

basically I do something like this:


        Thread th = new Thread(new ThreadStart(StartListenThreaded));
	th.Start();

The method StartListenThread looks like this:

	private void StartListenThreaded()
		{
			IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
			IPEndPoint EndPoint = new IPEndPoint(ipAddress, port);
			Socket ss = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
				
				
			ss.Bind( EndPoint);
			ss.Listen(20);
			try
			{
				while(true)
				{
					Console.WriteLine("rnServer is waiting for a new connection..rn");
					Socket sock = ss.Accept();

					Console.WriteLine("Accepted connection form:"+sock.RemoteEndPoint);
					Connection con = new Connection(sock);
					

					Thread t = new Thread(new ThreadStart(con.ProcessOneRequest));
					t.IsBackground=true;
					t.Priority=ThreadPriority.BelowNormal;
					t.Start();
				}
			}
			catch (System.Exception e1) 
			{  Console.WriteLine("An Exception Occurred while Listening :" +e1.ToString()); }

		}

As mentioned above There are mostly some Word-Documents or PDF files send as the body of a request. So I need to parse the body and write the content to a file.

Currently I use this code to accomplish that:


	while (true) 
	{
	    if(socket.Available == 0)
		break;
	    
            n = socket.Receive(bytes);
	    if(n == 0)
		 break;

	    wr.Write(bytes,0,n); // wr is a BinaryWriter
	}			

Now my problem is that this loop breaks before all data is received from the socket. That means it runs into the socket.Available == 0 case and ends, but there is still data available. How did I find that out? Well during debugging the code.

With the debugger running and when stepping through the code, obviously leaves the SAP side more time to send its data.

When doing some Console.WriteLine() after the loop with the socket.Receive() I get results > 0. So there is still data available.

I am not asking an SAP question here. I am aware that the problem could also be on the SAP side. However I think it is a C# issue. Has anyone experienced similar problems with sockets? Am I doing something completely wrong in handling my socket? I also don´t think that I can use Asynchronous sockets beacuse I need to process incoming requests in a determined order.

I have also tryed to turn off Blocking mode by setting socket.Blocking = false but I found out that I cannon use that because I need NetworkStream at some point in my application and NetworkStream does not work without blocking mode.

Accepted Solutions (0)

Answers (1)

Answers (1)

reiner_hille-doering
Active Contributor
0 Kudos

Unfortunately I can't answer your question, but genererally I would recommend to handle HTTP not with pure sockets, but with the corresponding HTTP classes.

If you could accept running in IIS you would write a HTTPHandler.

Else you could use Indigo (allows HTTP hosted everywhere), WSE or Cassini (a simple ASP.NET Web Server available completely in C# source code).

Former Member
0 Kudos

I have evaluated several other possibilities before starting to implement HTTP on a socket basis. I only have this choice.

I have had a detailed look at Cassini before, but since you mentioned it in your post I looked at it more closely and I think I found a solution for my Problem.

Cassini uses some code like the following to poll for more data in a request. I am now using this mechanism in my application and it works fine.


		private int WaitForRequestBytes() 
		{
			int availBytes = 0;

			try 
			{
				Console.WriteLine("socket.Available: " + socket.Available);
				if (socket.Available == 0) 
				{
					// poll until there is data
					Console.WriteLine("Polling 100ms");
					socket.Poll(100000 /* 100ms */, SelectMode.SelectRead);

					if (socket.Available == 0 && socket.Connected) 
					{
						Console.WriteLine("Polling 1sec");
						socket.Poll(1000000 /* 1sec */, SelectMode.SelectRead);
						// socket.Poll(10000000 /* 10sec */, SelectMode.SelectRead);
					}
				}

				availBytes = socket.Available;
			}
			catch 
			{
			}

			return availBytes;
		}

So thanks for putting me in the right direction.

Mirco