The underlying connection was closed: The connection was closed unexpectedly. Data is too big?

13,192

What is your client-side configured as? You've displayed your server-side configuration, but don't forget that the client-side has it's own configuration settings.

Looking at your server-side configuration, it appears that the violation is occurring on the reception of the data on the client.

See here for an example. You can also do this programmatically as well.

Edit

Now I see in the comments that this ArrayList you are getting from the server contains your own user-defined type RFData. I believe now that this is likely the source of your problem.

Data Contracts describe the data that is being exchanged. Data Contracts are used between the Client and Server to serialize and de-serialize data that is being sent over the wire. You need to use Data Contracts/ Data Members when you are defining your own type to be used within the WCF model. Primitives as well as many of the built-in .NET types already have Data Contracts.

For your RFData type it would be something like this:

// Apply the DataContract to the type
[DataContract]
public class RFData
{
    // Apply the DataMemberAttribute to the various properties
    [DataMember]
    public double RFDouble { get; set; }
    [DataMember]
    public int RFInt { get; set; }
    [DataMember]
    public string RFString { get; set; }
}

I know you have several integers and doubles, but you get the gist. Here is a really helpful guide on Data Contracts from MSDN.

Share:
13,192
janderson
Author by

janderson

Updated on June 13, 2022

Comments

  • janderson
    janderson almost 2 years

    I have got a server/client relationship where the client pulls an ArrayList from the server. If I set the server to always send an empty ArrayList then I don't get this error. So clearly the problem is that my data is too big for the connection and that it's closing before all the data can get through.

    I have looked into this issue and I have added the features suggested by this question/answer: https://stackoverflow.com/a/285542/3036134 Many solutions suggest the same thing.

    I believe that I have implemented something incorrectly (I think it's most likely the Service Behaviour MaxItemsInObjectGraph as I am still getting the same error. I unfortunately can't figure out what's wrong with it though. Here's my code:

    The error I'm receiving:

    CommunicationException was unhandled. The underlying connection was closed: The connection was closed unexpectedly.
    

    My WCF Service Code:

    [ServiceContract]
    public interface IModelData
    {
        [OperationContract]
        ArrayList GetData();
    }
    
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, MaxItemsInObjectGraph = 2147483647)]
    public class ModelDataClient
    {
        ChannelFactory<IModelData> HttpFactory;
        IModelData HttpProxy;
    
        public ModelDataClient()
        {
            HttpFactory = new ChannelFactory<IModelData>(
                new BasicHttpBinding(),
                new EndpointAddress("http://localhost:8000/ModelData"));
    
            HttpProxy = HttpFactory.CreateChannel();
        }
    
        public ArrayList GetData()
        {
            return HttpProxy.GetData();
        }
    }
    
    [ServiceBehavior(UseSynchronizationContext = false, InstanceContextMode = InstanceContextMode.Single, MaxItemsInObjectGraph = 2147483647)]
    public class ModelDataServer : IModelData
    {
        public delegate ArrayList GetData();
        public GetData _GetData { get; set; }
    
        public ModelDataServer()
        {
        }
    
        public ArrayList GetData()
        {
            return _GetData();
        }
    }
    

    My Client Side Code:

    public partial class MainForm : Form
    {  
        private ModelDataClient Client;
    
        public MainForm()
        {
            InitializeComponent();
    
            Client = new ModelDataClient();
        }
    
        private void Refresh()
        {
            ArrayList dataList = Client.GetData();
            // ********** ERROR POINTS TO LINE ABOVE!!!!!!!!!!!!!!!!!!!!
    
            // do something with datalist
        }
    }   
    

    My Server Side Code:

    public partial class ScraperForm : Form
    {
        ServiceHost Host;
        ModelDataServer DataServer;
    
        ArrayList Data;
    
        public ScraperForm()
        {
            InitializeComponent();
    
            #region Start Data Server
            DataServer = new ModelDataServer();
            DataServer._GetData = new ModelDataServer.GetData(this.GetData);
    
            BasicHttpBinding bhttpb = new BasicHttpBinding();
    
            bhttpb.MaxBufferSize = 2147483647;
            bhttpb.MaxReceivedMessageSize = 2147483647;
            bhttpb.ReaderQuotas.MaxDepth = 32;
            bhttpb.ReaderQuotas.MaxStringContentLength = 8388608;
            bhttpb.ReaderQuotas.MaxArrayLength = 16384;
            bhttpb.ReaderQuotas.MaxBytesPerRead = 4096;
            bhttpb.ReaderQuotas.MaxNameTableCharCount = 16384;
    
    
            Host = new ServiceHost(DataServer, new Uri[]
                {
                    new Uri("http://localhost:8000")
                });
    
            Host.AddServiceEndpoint(typeof(IModelData),
                bhttpb,
                "ModelData");
    
            Host.Open();
    
            Data = new ArrayList();
        }
    
        private void CloseSever()
        {
            Host.Close();
        }
    
        public void UpdateData() // Run on a timer
        {
            ArrayList Data = new ArrayList()
    
            // Update Data
        }
    
        public ArrayList GetData() // This is called by server which is called by client
        {
            return Data;           // no error if I return new ArrayList();
        }
    }
    

    EDIT: Would the problem be being caused by not having DataContract/DataMembers?

    UPDATE I have rebuilt my new implementation from the ground up using this tutorial (and the related ones): http://blogs.msdn.com/b/brunoterkaly/archive/2013/10/28/wcf-programming-how-to-write-a-client-app-that-connects-to-a-wcf-service.aspx (For anyone interested).

    Instead of using an ArrayList (lots of unboxing) and a Typed List (comes out as an array if used with WCF), I have instead opted to pass my data using a string with the following format: "~" to denote the start of a new member of the list "," to denote the end of one of the datatypes in my custom one. So it might look like "~NAME,1.29,1,4,123.1~NAME,1.23,3,1,13.2" etc. I would suggest people who want to use lists use this instead.

    I have run into a new problem with my new implementation, likely the same/similar problem. Please see my new question: Object reference not set to an instance of an object - WCF Service and Delegates (WCF Hosted before Delegate is instantiated)

    Thanks for your help everyone.

  • janderson
    janderson over 10 years
    Hi Derek, thanks for your help. I don't have an app.config file in my project. Is there another way to retrieve this config file?
  • Lex Li
    Lex Li over 10 years
    @Watson, you should make it clear what is your client/server project type. app.config is only available in some projects. For other projects you should see web.config or servicereferences.clientconfig. If your client project is a WinForms project, you can create app.config if it is not yet in the project.
  • janderson
    janderson over 10 years
    Thanks for your help Derek, I really appreciate it. Please see my "Update" at the bottom of my post.
  • janderson
    janderson over 10 years
    @DerekW see the above comment (forgot to tag)