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