0

我一直在使用套接字在 C# 中发送数据并且它正在工作,使用以下代码:

string ipAddress = "x.y.z.a";   // replace with a real IP address
int port = 2809;
string data = "foo";

Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

if (!clientSocket.Connected)
    clientSocket.Connect(IPAddress.Parse(ipAddress), port);

clientSocket.Send(Encoding.UTF8.GetBytes(data));
clientSocket.Disconnect(true);
clientSocket.Close();
clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

现在我希望它接收数据,但我无法让它工作,因为当我添加socket.Receive()程序时崩溃。谁能指出我正确的方向?

4

1 回答 1

2

正如乔恩所建议的那样您尝试添加接收代码的位置还不是很清楚。我的意思是,您示例的最后一行有点令人困惑,因为您首先关闭了套接字,然后创建了一个新的。为什么?首先与“if (!clientSocket.Connected)”类似;如果您创建一个新的套接字,则无需检查它是否已连接。当然不是,你只是创造了它!:-)

无论如何,如果我像这样在你之后添加一些代码:

byte[] receiveBuffer = new byte[1024];
clientSocket.Receive(receiveBuffer);

...并相应地将 and 更改为ipAddressport网络上已知的良好服务,我收到SocketException一条消息,上面写着“不允许发送或接收数据的请求,因为套接字未连接并且(在使用数据报套接字发送时) sendto 调用)没有提供地址”

但是,如果我插入接收代码,使发送/接收看起来像这样:

int bytesSent = clientSocket.Send(Encoding.UTF8.GetBytes(data));

var receiveBuffer = new byte[1024];
var sb = new StringBuilder();
int receivedBytes;
while ((receivedBytes = clientSocket.Receive(receiveBuffer)) != 0)
{
    // NOTE: this presumes that the data coming from the remote end is ASCII-
    // encoded, which might not be the case at all. Don't copy this approach
    // blindly without thinking
    string s = Encoding.ASCII.GetString(receiveBuffer, 0, receivedBytes);
    sb.Append(s);
}

var response = sb.ToString(); // at this point you should have all the data that
                              // has been received from the remote, so far.

clientSocket.Disconnect(true);
clientSocket.Close();

这段代码对我有用;它给了我对我的请求的回应(在我的情况下大约 3 KiB)。

不过,在更哲学/体系结构的层面上,我绝对建议,如果你真的不需要进入套接字级别(无论出于何种原因),更喜欢使用框架的更高级别的类之一。WebClient是一种替代方案(适用于所有 >1.1 版本的框架,例如,几乎所有目前正在使用的版本)。HttpClient是另一个,如果您在 .NET 4.5 上(也有来自NuGet的后向端口

当然,这盲目地假定您想要做的是执行 HTTP 请求(事实证明,这在当今很常见)。还有其他替代方案,例如用于 FTP 的FtpWebRequest等。

根据我的经验(作为一名程序员工作了 10 多年),实际上必须深入到套接字级别是非常罕见的,尤其是最近考虑到 BCL(基本类库,例如 Microsoft 提供的 .NET 标准程序集)或 NuGet。这样的现有客户具有巨大的巨大优势,其他人已经花费了大量时间,找出错误,怪癖等等,因此您可以开始专注于您真正想要解决的问题,而不是修复错误实际上之前已经修复了很多很多次......

(当然,也有例外,但我觉得这绝对是一般的经验法则。)

于 2013-10-04T19:28:29.363 回答