zoukankan      html  css  js  c++  java
  • [收藏]General things to take into consideration while doing socket programming.

    I had to recently write a client-server socket application and so I was mulling over all that needs to be considered when programming with sockets especially using TCP. I have summarized them below.

     

    1. Partial Packets – Never assume that how much ever you send from one side will be received at the other side in a single receive. You might have to queue in multiple receives. So incase you need the data in full for processing, send the size of the data before the data itself, so that you can wait for so many bytes to arrive before processing the data,

     

    2. Message boundaries :

    a. A single receive posted at B might get all the data sent by A.

    b. Or the sends might be broken and merged with subsequent sends - If A sends abcde followed by fghijkl where a..l represent different bytes, B can receive  abc, then in another receive defg and then hijkl or as abcdefghij and then kl

    [http://blogs.msdn.com/joncole gives sample code and explains this in great detail]

     

    3. The above argument is true for subsequent synchronous sends. When asynchronous sends are queued, there is no guarantee in the order the sends are processed, i.e., The second BeginSend call could have been processed before the first.

     

    3. When A does a graceful close, read on B returns 0 bytes. This is the most commonly used mechanism to know that the other end has closed the connection.

     

    4. When Nagling is enabled, the small sends are delayed. So if you have small packets that need to be sent soon, disable nagling, by setting Socket.NoDelay to true.

     

    5. Eventhough you supply a very high value in socket.Listen parameter, the OS has a limit on these values (http://support.microsoft.com/kb/127144/en-us)

     

    From the Support site:

    The WinSock listen() call backlog parameter under Windows NT version 3.5 and 3.51 accepts a maximum value of 100.

    The maximum backlog parameter is 5 on Windows NT 4.0 Workstation, and 200 on Windows NT 4.0 Server.

    WinSock server applications use the listen() call to establish a socket for listening for incoming connections. This calls second parameter, backlog, is defined as the maximum length to which the queue of pending connections may grow.

    The WinSock version 1.1 specification states the maximum value for the backlog parameter is 5. However, Windows NT version 3.5 accepts up to 100 for this value.

     

    6. To prevent the TCP Syn attack, whenever a SYN is received, a SYN+ACK is immediately sent irrespective of whether the server can handle the request or not. This SynProtection mechanism is available in Win2k3 and higher. How does this get into our path when we use System.Net to do socket programming as we don’t deal with SYN packets?

     

    Here is the scenario.

    If suppose the server listens with a backlog of 2 (just for the sake of explanation I have used the value 2) and it has not yet issued the Accept call. If 5 clients try to connect, the connect from all the 5 clients will succeed as the clients get SYN +ACK immediately from the server. But when they try to send data before the server issues Accept, the send fails with the following exception. Only on a send or the first IO request, the winsock allocates data structures for the socket.

     

     Here is the stack trace from my small repro code.

     

    System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host

       at System.Net.Sockets.Socket.Send(Byte[] buffer, Int32 offset, Int32 size, So

    cketFlags socketFlags)

       at System.Net.Sockets.Socket.Send(Byte[] buffer)

       at client.Run()

    So a successful connect need not necessarily mean that client is connected. A subsequent send should pass too.

     

    7. When the socket is disconnected (note: not closed), you can use the same socket only to connect to some other server and through one of the asynchronous APIS only

     

    8. There is no send/receive timeout for asynchronous calls. They are valid only for synchronous as it is very difficult to cancel overlapped calls, when timeout occurs.

     

    clientSocket.ReceiveTimeout =1000;

    byte[] b=new byte[1000];

    clientSocket.BeginReceive(b, 0, 100, SocketFlags.None, new AsyncCallback(ReceiveCallback), clientSocket);

     

    when there is no send on the other end, the ReceiveCallback is never called at all, even after the receivetimeout that has been set.

    Published Monday, June 26, 2006 6:19 PM by malarch

    Comments

    Tuesday, July 18, 2006 1:50 AM by Windows Network Development

    # Recent System.Net Related Postings

    Recently, a number of current and former System.Net team members have posted about various managed code network...

    # Recent System.Net Related Postings » Wagalulu - Microsoft » » Recent System.Net Related Postings

    Thursday, December 14, 2006 12:23 PM by Jon Cole's WebLog

    # Simple Message Framing Sample for TCP Socket

    A common misunderstanding for developers new to network programming over TCP sockets is how messages

    Thursday, December 14, 2006 12:24 PM by Jon Cole's WebLog

    # Simple Message Framing Sample for TCP Socket - Part 2 (Asynchronous)

    As a follow up to my last post ( http://blogs.msdn.com/joncole/archive/2006/03/20/555721.aspx ) I decided

  • 相关阅读:
    IIS应用程序池自动化回收脚本
    gitlab修改克隆地址
    docker安装的gitalb备份及数据迁移
    docker安装gitlab
    docker安装的gitlab备份脚本
    sql server 2016 维护计划执行,提示执行失败。有关详细信息,请参阅维护计划和sql server 代理作业历史记录日志。
    SSH使用证书登录
    docker搭建 rabbitmq集群
    VMware Workstation Pro设置nat模式上网
    docker-compose搭建discuz论坛
  • 原文地址:https://www.cnblogs.com/verygis/p/1227117.html
Copyright © 2011-2022 走看看