C#的socket收发数据过程中,如何判断连接断开、收发方主动终止、发送错误、接收错误等状态

主  题:  C#的socket收发数据过程中,如何判断连接断开、收发方主动终止、发送错误、接收错误等状态
作  者:  cq_lqj (程序员秘书)
等  级:  ^
信 誉 值:  100
所属社区:  .NET技术 C#
问题点数:  100
回复次数:  22
发表时间:  2004-11-21 23:13:49

C#的socket的Poll在收发数据过程中,测试出的状态不好用
Connected的状态不是实时的
发送方抛出错误无法判断是接收方主动终止还是网络线路断开了
接收方更不行,就是网络线路断开或发送方主动终止都不会报错误

我看了看以前发的贴子,好象都没有好的办法,难道C#的socket这么弱?
用C++的socket开发,收、发方都能很好的判断出对方主动终止还是网络断开!

C#的高手们出来说说话!!!!!!!!!!!!!



回复人: windinwing(潇笑) ( 五级(中级)) 信誉:72 2004-11-22 0:58:52 得分: 0

异常处理其实很强大的

catch(SocketException x){
    if(x.ErrorCode == 10004){
    }
}

还有写自已的异常处理类

#region public enum ReadReplyCode

/// <summary>
/// Reply reading return codes.
/// </summary>
public enum ReadReplyCode
{
    /// <summary>
    /// Read completed successfully.
    /// </summary>
    Ok = 0,

    /// <summary>
    /// Read timed out.
    /// </summary>
    TimeOut = 1,

    /// <summary>
    /// Maximum allowed Length exceeded.
    /// </summary>
    LengthExceeded = 2,

    /// <summary>
    /// Connected client closed connection.
    /// </summary>
    SocketClosed = 3,

    /// <summary>
    /// UnKnown error, eception raised.
    /// </summary>
    UnKnownError = 4,
}

#endregion

/// <summary>
/// Summary description for ReadException.
/// </summary>
public class ReadException : System.Exception
{
    private ReadReplyCode m_ReadReplyCode;

    /// <summary>
    /// 
    /// </summary>
    /// <param name="code"></param>
    /// <param name="message"></param>
    public ReadException(ReadReplyCode code, string message) : base(message)
    {
        m_ReadReplyCode = code;
    }

    #region Properties Implementation
    /// <summary>
    /// Gets read error.
    /// </summary>
    public ReadReplyCode ReadReplyCode
    {
        get { return m_ReadReplyCode; }
    }
    #endregion

    ReadReplyCode replyCode = ReadReplyCode.Ok;

try {
    _FixedStack stack = new _FixedStack(terminator);
    long readedCount = 0;
    int nextReadWriteLen = 1;
    while (nextReadWriteLen > 0)
    {
        //Read byte(s)
        byte[] b = new byte[nextReadWriteLen];
        int countRecieved = this.Receive(b);
        if (countRecieved > 0)
        {
            readedCount += countRecieved;

            // Write byte(s) to buffer, if length isn't exceeded.
            if (readedCount <= maxLength)
            {
                storeStream.Write(b, 0, countRecieved);
            }

            // Write to stack(terminator checker)
            nextReadWriteLen = stack.Push(b, countRecieved);
        }
        // Client disconnected
        else
        {
            return ReadReplyCode.SocketClosed;
        }

        OnActivity();
    }

    // Check if length is exceeded
    if (readedCount > maxLength)
    {
        return ReadReplyCode.LengthExceeded;
    }

    // If reply is ok then remove chars if any specified by 'removeFromEnd'.
    if (replyCode == ReadReplyCode.Ok && removeFromEnd.Length > 0)
    {
        storeStream.SetLength(storeStream.Length - removeFromEnd.Length);
    }

    // Logging stuff
    if (m_pLogger != null)
    {
        if (storeStream is MemoryStream && storeStream.Length < 200)
        {
            MemoryStream ms = (MemoryStream)storeStream;
            m_pLogger.AddReadEntry(m_pEncoding.GetString(ms.ToArray()));
        }
        else
        {
            m_pLogger.AddReadEntry("Big binary, readed " + readedCount.ToString() + " bytes.");
        }
    }
}
catch (Exception x)
{
    replyCode = ReadReplyCode.UnKnownError;

    if (x is SocketException)
    {
        SocketException xS = (SocketException)x;
        if (xS.ErrorCode == 10060)
        {
            return ReadReplyCode.TimeOut;
        }
    }
}

return replyCode;

这些问题全解决了 呵呵

回复人: cq_lqj(程序员秘书) ( 一级(初级)) 信誉:100 2004-11-22 1:29:47 得分: 0

老大是不是写得有点乱
_FixedStack是什么
你这段代码不好调试啊?再全一点好吗,老大

回复人: windinwing(潇笑) ( 五级(中级)) 信誉:72 2004-11-22 2:11:28 得分: 0

晕的_FixedStack是一个封装的byte位操作类,不用管他
只是一种处理思路,不是拿来调试的,不然又要一堆代码

回复人: cxyPioneer(sunny) ( 四级(中级)) 信誉:100 2004-11-22 8:28:55 得分: 0

up

回复人: 520NET(随风) ( 五级(中级)) 信誉:100 2004-11-22 8:30:25 得分: 0

LG

回复人: xiaoslong(龙哥) ( 五级(中级)) 信誉:65 2004-11-22 9:13:14 得分: 0

帮你顶

回复人: jimh(jimmy) ( 五级(中级)) 信誉:100 2004-11-22 9:16:03 得分: 0

回复人: cdo(cdo) ( 三级(初级)) 信誉:100 2004-11-22 9:51:30 得分: 0

帮你顶:)

回复人: cq_lqj(程序员秘书) ( 一级(初级)) 信誉:100 2004-11-22 14:41:51 得分: 0

帮我顶哈

回复人: cq_lqj(程序员秘书) ( 一级(初级)) 信誉:100 2004-11-23 8:38:21 得分: 0

up

回复人: cq_luqinjian(深入学习C#) ( 一级(初级)) 信誉:100 2004-11-23 13:51:21 得分: 0

顶起不放

回复人: catman3000(catman) ( 二级(初级)) 信誉:91 2004-11-23 16:44:48 得分: 0

帮你顶

回复人: luncashcage(自清闲) ( 一级(初级)) 信誉:100 2004-11-24 8:52:26 得分: 0

这个代码写的确实有点乱。没空细心看的阿。

回复人: xiaoslong(龙哥) ( 五级(中级)) 信誉:65 2004-11-24 9:03:25 得分: 0

帮你顶

回复人: kgd198294(来自湖南) ( 一级(初级)) 信誉:100 2004-11-24 10:06:49 得分: 0

有两种方法:
1:用try catch捕捉
2:设置好要接收数据的总长度,当数据接收完后。数据是否达到要求,如未达到要求,则可知道对方,半路中断

回复人: singleflower(shifan(愿父亲安息)) ( 五级(中级)) 信誉:100 2004-11-24 10:16:24 得分: 0

catch(SocketException x){
    if(x.ErrorCode == 10004){
    }
}

我觉得这种方式最好,或者用个SWITCH,这样扩充性好,如果要扑捉新的错误,加个CASE很容易的

回复人: cq_lqj(程序员秘书) ( 一级(初级)) 信誉:100 2004-11-24 13:00:46 得分: 0

楼上两位朋友,你们用socket编程传输文件没有?

用try catch捕捉,发送端没有问题的,对方主动终止或线路断开都会抛出错误的!可以很好的处理。
关键是接收端:当只接收了部分数据时,对方主动终止或线路断开,iNumByte=rBinarySocket.Receive(pBuf);不会抛出任何错误
如果这时线路断开它只有不停的循环接收。

while(uiTotal < uilength)
{
    ......
    iNumByte=rBinarySocket.Receive(pBuf);
    ......
    uiTotal+=iNumByte;
    Thread.Sleep(1);
}

回复人: TigerSuper(菜鸟) ( 一级(初级)) 信誉:100 2004-11-24 14:02:37 得分: 0

UP

回复人: cq_lqj(程序员秘书) ( 一级(初级)) 信誉:100 2004-11-25 8:15:01 得分: 0

up

回复人: cq_lqj(程序员秘书) ( 一级(初级)) 信誉:100 2004-11-25 11:11:12 得分: 0

up

回复人: yzh0523(水手) ( 四级(中级)) 信誉:100 2004-11-25 11:25:52 得分: 0

mark

回复人: cq_lqj(程序员秘书) ( 一级(初级)) 信誉:100 2004-11-29 11:01:11 得分: 0

up

Contributors: FHL