c#socket传输文件

c#socket传输文件

2023年7月15日发(作者:)

c#socket传输⽂件int port = 1234;int port = 1234; IPAddress ip = ("127.0.0.1"); socket = new Socket(etwork,,); IPEndPoint iep = new IPEndPoint(ip,port); //ng = false; (iep); (10); ine(""); try { for (int i = 0; i < 10;i++ ) {

} } catch { ine("异常!"); (); }接收端

private void Receive(Socket socket)

{

NetworkStream ns = new NetworkStream(socket);

FileStream fs = new FileStream("c:", Create);

bool isRead = true;

while (isRead)

{

int count = (this._receiveBuf, 0, this._);

int datanum = 0;

datanum = 32(this._receiveBuf, 0); //从buffer中的前4个字节读出count

if (datanum > 0) //确定每次要接受多少字节数

{

(this._receiveBuf, 4, datanum);

}

else //如果接受字节数为0 就推出

{

isRead = false;

}

}

= "⽂件传输成功";

();

}

---------------------

发送端

private void btSend_Click(object sender, rgs e)

{

if (this._isConnect)

{

_ns = _eam();

string path = ();

FileStream fs = new FileStream(path, );

int sendCount = 0;

byte[] countbuffer = null;

byte[] clientbuffer = new byte[1004];

while (sendCount < && _te)

{

int count = (_sendBuf, 0, _); //读出要发送的数据

countbuffer = es(count);

(clientbuffer,0);

_(clientbuffer, 4);

this._(clientbuffer, 0, 4 + count); //写⼊⽹络流 sendCount += count;

}

countbuffer = es(0); //发送完⽂件后 发送count = 0

this._(countbuffer, 0, ); //使接收端停⽌

_();

();

}

}你为什么不把这两种⽅案结合在⼀起呢?

⾸先把⽂件的总长度和每次发送的⼤⼩先发送出去,等接收端接受并分析,然后开始。

⽐如每次发送4K(这是操作系统⽂件管理中使⽤到的最⼩⽂件⼤⼩,你可以看看你系统中的任何⼀个⽂件,占⽤空间都是4K的整数倍),

最后⼀次可能会少与4K,但是接受⽅是可以计算出来的。

必要时,你可以使⽤多线程,分段发送,接收端收集后分段组合,这还要多使⽤⼀个段号码。

socket是最底层的类,传输效率最⾼!

对于你说的异步操作,⼀句话说不清楚,基本上可以⽤“⾮阻塞模型”来概括,就是调⽤后⽴马返回,不是等到操作完成后才返回!

打个⽐⽅:阻塞模型

while(isok)

{

readdata(data);//从⽂件读数据

send(data); //⼀直等到data发送完毕后才返回,其实这期间本来可以进⾏下⼀次读操作

//影响了效率。

if(读完)

isok=false;

else

isok=true;

}

⾮阻塞模型,可以在发送过程中进⾏读取操作,提⾼了效率。

当然,在第⼆次发送前,必须等待第⼀次发送操作完成才⾏,需要检测和控制!while (sendCount < && _te)

{

int count = (_sendBuf, 0, _); //读出要发送的数据

countbuffer = es(count);

(clientbuffer,0);

_(clientbuffer, 4);

this._(clientbuffer, 0, 4 + count); //写⼊⽹络流

sendCount += count;

}

有点乱:你每次读取1000还是1004??不是前四个字节是长度吗?为什么从⽂件⾥读取1004个字节啊?

BeginReceiveFrom ⽅法启动从远程主机异步读取⽆连接数据报的操作。调⽤ BeginReceiveFrom ⽅法将使您能够在单独的执⾏线程中接收数据。

您可以创建⼀个实现 AsyncCallback 委托的回调⽅法并将它的名称传递给 BeginReceiveFrom ⽅法。为此,您的 state 参数⾄少必须包含⽤于通信的已连接或默认 Socket。如果您的回调需要更多信息,则可以创建⼀个⼩型类来保存 Socket 和其他必需的信息。通过 state 参数将此类的⼀个实例传递给 BeginReceiveFrom ⽅法。

回调⽅法应调⽤ EndReceiveFrom ⽅法。当应⽤程序调⽤ BeginReceiveFrom 时,系统将会使⽤单独的线程来执⾏指定的回调⽅法,并将在 EndReceiveFrom 上⼀直阻⽌到 Socket 读取数据或引发异常为⽌。如果想要在调⽤ BeginReceiveFrom ⽅法后使原始线程阻⽌,请使⽤e。当需要原始线程继续执⾏时,请在回调⽅法中调⽤ T:ResetEvent 的 Set ⽅法。有关如何编写 callback ⽅法的其他信息,请参见 Callback ⽰例。

注意

在调⽤ BeginReceiveFrom 之前,必须使⽤ Bind ⽅法显式地将 Socket 绑定到本地终结点,否则 BeginReceiveFrom 将会引发SocketException。

该⽅法将数据读⼊ buffer 参数中,并捕获从其发送数据的远程主机终结点。有关如何检索此终结点的信息,请参考 EndReceiveFrom。如果打算从未知主机或多个主机异步接收⽆连接的数据报,则最适合使⽤此⽅法。在这些情况下, BeginReceiveFrom 将会读取本地⽹络缓冲区接收到的第⼀个排队数据报。如果您接收到的数据报⼤于 buffer 的⼤⼩,则 BeginReceiveFrom ⽅法将在 buffer 中尽可能多地填充消息内容,并引发 SocketException。如果您使⽤的是不可靠协议,多余的数据将会丢失。⽽如果当前使⽤的是可靠协议,则服务提供程序将保留多余的数据,⽽且通 过使⽤⼀个⾜够⼤的缓冲区调⽤ BeginReceiveFrom ⽅法来检索这些数据。

虽然 BeginReceiveFrom 是⽤于⽆连接协议的,但您同样可以使⽤⾯向连接的协议。如果选择这样做,则必须通过调⽤ Connect /BeginConnect ⽅法来建⽴远程主机连接,或者调⽤ Accept 或 BeginAccept ⽅法来接受传⼊的连接请求。如果在建⽴连接或接受连接之前就调⽤了 BeginReceiveFrom ⽅法,则您将得到 SocketException。您也可以在调⽤ BeginReceiveFrom ⽅法之前,为⽆连接协议建⽴默认远程主机。在上述任何⼀种情况下,BeginReceiveFrom ⽅法都会忽略 remoteEP 参数,并且只从已连接的或默认的远程主机接收数据。

对于⾯向连接的套接字,BeginReceiveFrom 将读取所有可⽤的数据,直到达到 size 参数所指定的字节数。

若要取消挂起的 BeginReceiveFrom,请调⽤ Close ⽅法。

下⾯的代码⽰例异步接收来⾃远程主机的⽆连接数据报。

BeginReceiveFrom ⽅法启动从远程主机异步读取⽆连接数据报的操作。调⽤ BeginReceiveFrom ⽅法将使您能够在单独的执⾏线程中接收数据。

您可以创建⼀个实现 AsyncCallback 委托的回调⽅法并将它的名称传递给 BeginReceiveFrom ⽅法。为此,您的 state 参数⾄少必须包含⽤于通信的已连接或默认 Socket。如果您的回调需要更多信息,则可以创建⼀个⼩型类来保存 Socket 和其他必需的信息。通过 state 参数将此类的⼀个实例传递给 BeginReceiveFrom ⽅法。

回调⽅法应调⽤ EndReceiveFrom ⽅法。当应⽤程序调⽤ BeginReceiveFrom 时,系统将会使⽤单独的线程来执⾏指定的回调⽅法,并将在 EndReceiveFrom 上⼀直阻⽌到 Socket 读取数据或引发异常为⽌。如果想要在调⽤ BeginReceiveFrom ⽅法后使原始线程阻⽌,请使⽤e。当需要原始线程继续执⾏时,请在回调⽅法中调⽤ T:ResetEvent 的 Set ⽅法。有关如何编写 callback ⽅法的其他信息,请参见 Callback ⽰例。

注意

在调⽤ BeginReceiveFrom 之前,必须使⽤ Bind ⽅法显式地将 Socket 绑定到本地终结点,否则 BeginReceiveFrom 将会引发SocketException。

该⽅法将数据读⼊ buffer 参数中,并捕获从其发送数据的远程主机终结点。有关如何检索此终结点的信息,请参考 EndReceiveFrom。如果打算从未知主机或多个主机异步接收⽆连接的数据报,则最适合使⽤此⽅法。在这些情况下, BeginReceiveFrom 将会读取本地⽹络缓冲区接收到的第⼀个排队数据报。如果您接收到的数据报⼤于 buffer 的⼤⼩,则 BeginReceiveFrom ⽅法将在 buffer 中尽可能多地填充消息内容,并引发 SocketException。如果您使⽤的是不可靠协议,多余的数据将会丢失。⽽如果当前使⽤的是可靠协议,则服务提供程序将保留多余的数据,⽽且通 过使⽤⼀个⾜够⼤的缓冲区调⽤ BeginReceiveFrom ⽅法来检索这些数据。

虽然 BeginReceiveFrom 是⽤于⽆连接协议的,但您同样可以使⽤⾯向连接的协议。如果选择这样做,则必须通过调⽤ Connect /BeginConnect ⽅法来建⽴远程主机连接,或者调⽤ Accept 或 BeginAccept ⽅法来接受传⼊的连接请求。如果在建⽴连接或接受连接之前就调⽤了 BeginReceiveFrom ⽅法,则您将得到 SocketException。您也可以在调⽤ BeginReceiveFrom ⽅法之前,为⽆连接协议建⽴默认远程主机。在上述任何⼀种情况下,BeginReceiveFrom ⽅法都会忽略 remoteEP 参数,并且只从已连接的或默认的远程主机接收数据。

对于⾯向连接的套接字,BeginReceiveFrom 将读取所有可⽤的数据,直到达到 size 参数所指定的字节数。

若要取消挂起的 BeginReceiveFrom,请调⽤ Close ⽅法。

下⾯的代码⽰例异步接收来⾃远程主机的⽆连接数据报。

C# codeIPHostEntry lipa = e("");IPEndPoint lep = new IPEndPoint(sList[0], 11000);Socket s = new Socket(sFamily, , );IPEndPoint sender = new IPEndPoint(, 0);EndPoint tempRemoteEP = (EndPoint)sender;t(sender);try{ while(true){ (); StateObject so2 = new StateObject(); cket = s; ine("Attempting to Receive data from ");

eceiveFrom(, 0, _SIZE,0, ref tempRemoteEP, new AsyncCallback(Async_Send_eFrom_Callback), so2);

e(); }}catch (Exception e){ ine(ng());}在端⼝ 11000 上建⽴ UdpClient 连接。将很短的字符串消息发送到两个单独的远程主机。Receive ⽅法在接收消息前阻⽌执⾏。使⽤传递给Receive 的 IPEndPoint 可以显⽰响应主机的标识。

C# code// This constructor arbitrarily assigns the local port ent udpClient = new UdpClient(11000);try{ t("", 11000); // Sends a message to the host to which you have connected. Byte[] sendBytes = es("Is anybody there?");

(sendBytes, ); // Sends a message to a different host using optional hostname and port parameters. UdpClient udpClientB = new UdpClient(); (sendBytes, , "AlternateHostMachineName", 11000); //IPEndPoint object will allow us to read datagrams sent from any source. IPEndPoint RemoteIpEndPoint = new IPEndPoint(, 0); // Blocks until a message returns on this socket from a remote host. Byte[] receiveBytes = e(ref RemoteIpEndPoint);

string returnData = ing(receiveBytes); // Uses the IPEndPoint object to determine which of these two hosts responded. ine("This is the message you received " + ng()); ine("This message was sent from " + ng() + " on their port number " + ng()); (); ();

}

catch (Exception e ) { ine(ng()); }另外如果你想保证传输的质量的话,⽤TCP/IP协议吧,它的优点是可以控制传输中的质量(降低出错率),缺点是效率稍微低点。

TcpClient 类提供了⼀些简单的⽅法,⽤于在同步阻⽌模式下通过⽹络来连接、发送和接收流数据。

为使 TcpClient 连接并交换数据,使⽤ TCP ProtocolType 创建的 TcpListener 或 Socket 必须侦听是否有传⼊的连接请求。可以使⽤下⾯两种⽅法之⼀连接到该侦听器:

创建⼀个 TcpClient,并调⽤三个可⽤的 Connect ⽅法之⼀。

使⽤远程主机的主机名和端⼝号创建 TcpClient。此构造函数将⾃动尝试⼀个连接。

注意

如果要在同步阻⽌模式下发送⽆连接数据报,请使⽤ UdpClient 类。

给继承者的说明 要发送和接收数据,请使⽤ GetStream ⽅法来获取⼀个 NetworkStream。调⽤ NetworkStream 的 Write 和 Read ⽅法与远程主机之间发送和接收数据。使⽤ Close ⽅法释放与 TcpClient 关联的所有资源。

下⾯的代码⽰例建⽴ TcpClient 连接。

C# codestatic void Connect(String server, String message)

{ try

{// Create a TcpClient.// Note, for this client to work you need to have a TcpServer

// connected to the same address as specified by the server, port// 32 port = 13000;TcpClient client = new TcpClient(server, port);// Translate the passed message into ASCII and store it as a Byte [] data = es(message);

// Get a client stream for reading and writing.// Stream stream = eam();NetworkStream stream = eam();// Send the message to the connected TcpServer.

(data, 0, );ine("Sent: {0}", message);

// Receive the se.// Buffer to store the response = new Byte[256];// String to store the response ASCII responseData = ;// Read the first batch of the TcpServer response 32 bytes = (data, 0, );responseData = ing(data, 0, bytes);ine("Received: {0}", responseData);

// Close ();

();

}

catch (ArgumentNullException e)

{ine("ArgumentNullException: {0}", e); }

catch (SocketException e)

{ine("SocketException: {0}", e); } ine("n Press Enter "); ();

发布者:admin,转转请注明出处:http://www.yc00.com/xiaochengxu/1689409959a243502.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信