C# 确保插座连接完成,然后进行处理

C# 确保插座连接完成,然后进行处理,c#,sockets,C#,Sockets,我有一个服务器,它通过套接字接收字符串并对其进行操作。我想向服务器发送一个字符串,读取答案,发送另一个字符串,然后等待第二个字符串上的答案最终关闭事务。下面的代码是我实现这一目标的过程。当我发送第一个字符串时,我会得到一个回复,但一旦我发送第二个字符串,程序就会以一种无休止的思考方式“冻结”(而不是实际冻结) 我要发送到的服务器不是我的,因此我无法从中发布任何代码。不过我已经在本地运行了。我期待的答复大约是50-60个字符。我怀疑应用程序从未完成,我想做的是检查事务是否完成,然后关闭它。因为第一

我有一个服务器,它通过套接字接收字符串并对其进行操作。我想向服务器发送一个字符串,读取答案,发送另一个字符串,然后等待第二个字符串上的答案最终关闭事务。下面的代码是我实现这一目标的过程。当我发送第一个字符串时,我会得到一个回复,但一旦我发送第二个字符串,程序就会以一种无休止的思考方式“冻结”(而不是实际冻结)

我要发送到的服务器不是我的,因此我无法从中发布任何代码。不过我已经在本地运行了。我期待的答复大约是50-60个字符。我怀疑应用程序从未完成,我想做的是检查事务是否完成,然后关闭它。因为第一个字符串正在工作,所以我想检查第二个字符串是否已完成

class test {

private Socket m_Socket;
private TcpClient m_Client = new TcpClient();

public Test()
{
    InitializeComponent();

    m_Socket = m_Client.Client;
}

private void DoIt()
{
    // Connect
    if (!m_Socket.IsBound)
        m_Socket.Connect(txtHost.Text, Convert.ToInt32(txtPort.Text));

    // Send first string
    try
    {
        string str = "asdfpojfdiogj589068d9fyugui";
        Send(m_Socket, Encoding.UTF8.GetBytes(str), 0, str.length, 10000);
    }
    catch (Exception e)
    {
        MessageBox.Show(e.Message);
    }

    //// Receive answer
    byte[] buffer = new byte[48];
    Receive(m_Socket, buffer, 0, buffer.Length, 10000);
    Console.WriteLine("Answer 1: "+Encoding.UTF8.GetString(buffer, 0, buffer.Length));
    buffer = new byte[64];

    // Send string 2
    string str2 = "jasuidhj8348957y3478538hdjuhduihdfugv09im2390i490gfifjgiojdfiogj4893574y890dgydufighduifh";
    Send(m_Socket, Encoding.UTF8.GetBytes(str2), 0, str2.Length, 10000);

    // Receive answer2
    buffer = new byte[str2.Length];
    Receive(m_Socket, buffer, 0, buffer.Length, 10000);
    Console.WriteLine(Encoding.UTF8.GetString(buffer, 0, buffer.Length));
}

public void Send(Socket p_Socket, byte[] p_Buffer, int p_Offset, int p_Size, int p_Timeout)
{
        int startTickCount = Environment.TickCount;
        int sent = 0;
        do
        {
            if (Environment.TickCount > startTickCount + p_Timeout)
                throw new Exception("Timeout..");
            try
            {
                sent += p_Socket.Send(p_Buffer, p_Offset + sent, p_Size - sent, SocketFlags.None);
            }
            catch (SocketException ex)
            {
                if (ex.SocketErrorCode == SocketError.WouldBlock ||
                    ex.SocketErrorCode == SocketError.IOPending ||
                    ex.SocketErrorCode == SocketError.NoBufferSpaceAvailable)
                {
                    // socket buffer is probably full, wait and try again
                    System.Threading.Thread.Sleep(30);
                }
                else
                    throw ex;
            }
        } while (sent < p_Size);
}

public string Receive(Socket p_Socket, byte[] p_Buffer, int p_Offset, int p_Size, int p_Timeout)
{
    int startTickCount = Environment.TickCount;
    int received = 0;
    do
    {
        if (Environment.TickCount > startTickCount + p_Timeout)
            //throw new Exception("Timeout.");
            return p_Buffer.ToString();
        try
        {
            received += p_Socket.Receive(p_Buffer, p_Offset + received, p_Size - received, SocketFlags.None);
        }
        catch (SocketException ex)
        {
            if (ex.SocketErrorCode == SocketError.WouldBlock ||
                ex.SocketErrorCode == SocketError.IOPending ||
                ex.SocketErrorCode == SocketError.NoBufferSpaceAvailable)
            {
                // socket buffer is probably empty, wait and try again
                System.Threading.Thread.Sleep(30);
            }
            else
                throw ex;
        }
    } while (received < p_Size);
    return p_Buffer.ToString();
}
}
类测试{
专用插座m_插座;
私有TcpClient m_Client=新TcpClient();
公开考试()
{
初始化组件();
m_Socket=m_Client.Client;
}
私有无效DoIt()
{
//连接
如果(!m_Socket.IsBound)
m_Socket.Connect(txtHost.Text,Convert.ToInt32(txtPort.Text));
//发送第一个字符串
尝试
{
string str=“asdfpojfdiogj589068d9fyugui”;
Send(m_Socket,Encoding.UTF8.GetBytes(str),0,str.length,10000);
}
捕获(例外e)
{
MessageBox.Show(e.Message);
}
////收到答复
字节[]缓冲区=新字节[48];
接收(m_套接字,缓冲区,0,缓冲区长度,10000);
WriteLine(“答案1:+Encoding.UTF8.GetString(buffer,0,buffer.Length));
缓冲区=新字节[64];
//发送字符串2
字符串str2=“jasuidhj8348957y3478538hjhuhduidfugv09im2390i490gfifjgiojdfioogj4893574y890dgyduighduifh”;
发送(m_套接字,编码.UTF8.GetBytes(str2),0,str2.Length,10000);
//接受回答2
缓冲区=新字节[str2.Length];
接收(m_套接字,缓冲区,0,缓冲区长度,10000);
WriteLine(Encoding.UTF8.GetString(buffer,0,buffer.Length));
}
公共无效发送(套接字p_套接字,字节[]p_缓冲区,int p_偏移量,int p_大小,int p_超时)
{
int startTickCount=Environment.TickCount;
int sent=0;
做
{
if(Environment.TickCount>startTickCount+p_超时)
抛出新异常(“超时…”);
尝试
{
sent+=p_Socket.Send(p_缓冲区,p_偏移量+sent,p_大小-sent,SocketFlags.None);
}
捕获(SocketException例外)
{
if(ex.SocketErrorCode==SocketError.WouldBlock||
ex.SocketErrorCode==SocketError.IOPending||
ex.SocketErrorCode==SocketError.NoBufferSpaceAvailable)
{
//套接字缓冲区可能已满,请稍候,然后重试
系统线程线程睡眠(30);
}
其他的
掷骰子;
}
}while(发送startTickCount+p_超时)
//抛出新异常(“超时”);
返回p_Buffer.ToString();
尝试
{
接收+=p_套接字.Receive(p_缓冲区,p_偏移量+接收,p_大小-接收,SocketFlags.None);
}
捕获(SocketException例外)
{
if(ex.SocketErrorCode==SocketError.WouldBlock||
ex.SocketErrorCode==SocketError.IOPending||
ex.SocketErrorCode==SocketError.NoBufferSpaceAvailable)
{
//套接字缓冲区可能为空,请稍候,然后重试
系统线程线程睡眠(30);
}
其他的
掷骰子;
}
}while(收到

流从方法DoIt()开始,该方法通过UI中的按钮调用

您确定服务器只接受两个字符串,不多也不少吗?如果它只接受一个,您将不得不重新连接并发送另一个,因为它似乎只是文本,如果您
telnet
到服务器的端口并手动执行您的过程,它是否正常工作?您确定服务器的第二个响应将与第二个请求的长度完全相同吗?因为它会卡在
Receive
中,等待(至少)一个字节到达。@PeterRitchie我还没试过。我试试看@不幸的是,我不知道telnet现在在Win8:P上是如何工作的,但是,我已经和服务器的所有者谈过了,他们已经检查了服务器的状态和工作状态。另外,我正在发送一个字符串,该字符串工作正常,第二个字符串存在问题:(