Socket学习4 文件传输

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using System.IO;
using System.Xml;

namespace App_MYCS.HDL_class
{
class my_socketfile
{
private string path = "F:\\SmartMovie.EXE";    //要发送的文件
        private Socket s;

private void listen()
        {
            string ip = "127.0.0.1";   //远程IP 这里定义为自己的机器
            IPAddress[] ih = Dns.GetHostAddresses(ip); //获得IP列表
            IPAddress newip = ih[0];      //获取IP地址            
            int port = 6789;              //定义端口
        IPEndPoint Conncet = new IPEndPoint(newip, port); //构造结点
            s = new Socket(AddressFamily.InterNetwork, SocketType.Stream,  ProtocolType.Tcp);                   //初始化socket 
     try
         {                                  
   s.Connect(Conncet);      //连接远程服务器
  if (s.Connected)   //如果连接成功 s.Connected 则为true 否则为 false
            {
            Console.WriteLine("连接成功");
              Thread t = new Thread(new ThreadStart(set)); //创建线程
                t.Start();                      //开始线程
                Console.WriteLine("发送完毕");     
}
            }catch(NullReferenceException e)
            {
              Console.WriteLine("{0}",e);
            }
}

//创建set函数
private void set()
{
Console.WriteLine("开始发送数据");
byte[] b = new byte[10000000];            //创建文件缓冲区,这里可以认为文件的最大值
FileStream file = System.IO.File.Open(path, FileMode.Open, FileAccess.Read);   //创建文件流
int start = 0;
int end = (int)file.Length;               //获取文件长度 文件传送如果有需要超过int的范围估计就要改写FileStream类了

try
{
while (end != 0)
{
int count = file.Read(b, start, end);      //把数据写进流
start += count;
end -= count;
}
while (start != 0)
{
int n = s.Send(b, end, start, SocketFlags.None);  //用Socket的Send方法发送流
end += n;
start -= n;
}

file.Close();     //关闭文件流
s.Close();        //关闭Socket
}
catch (NullReferenceException e)
{
Console.WriteLine("{0}", e);
}

}
/*
这样文件发送的模型就实现了
接下去实现文件的接收,首先要确定对方发送文件的长度,
* 其实上面的那段还要加入发送文件长度的功能,实现很简单,
* 就是发送int变量end ,然后要求接收代码返回一个Boolean确定是否发送,
* 这里为了更简明的说清楚原理并没有实现
            
*/

private void get()
{
string path = "G:\\da.exe";  //接收的文件
FileStream file = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write); //写入文件流
TcpListener listen = new TcpListener(6789);  //监听端口
Socket s1 = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);  //定义Socket并初始化
try
{
listen.Start();        //开始监听
s1 = listen.AcceptSocket();            //获取Socket连接
byte[] data = new byte[10000000];      //定义缓冲区
int longer = data.Length;
int start = 0;
int mid = 0;
if (s1.Connected)             //确定连接
{
Console.WriteLine("连接成功");
int count = s1.Receive(data, start, longer, SocketFlags.None);  //把接收到的byte存入缓冲区
mid += count;
longer -= mid;
while (count != 0)
{
count = s1.Receive(data, mid, longer, SocketFlags.None);
mid += count;
longer -= mid;
}
file.Write(data, 0, 1214134); //写入文件,1214134为文件大小,可以用socket发送获得,代码前面已经说明。
s1.Close();
file.Close();
}
}
catch (NullReferenceException e)
{
Console.WriteLine("{0}", e);
}

}

class my_sockets
{
string _responseStr;
///   <summary>
///   GET方式发送请求
///   </summary>
///   <param   name= "requestUrl "> 请求地址 </param>
///   <returns> 响应字符串 </returns>
public string SendRequest(string requestUrl)
{
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(requestUrl);
httpWebRequest.Method = "GET ";
WebResponse webResponse = httpWebRequest.GetResponse();
StreamReader responseStream = new StreamReader(webResponse.GetResponseStream(), System.Text.Encoding.UTF8);
_responseStr = responseStream.ReadToEnd();
webResponse.Close();
responseStream.Close();
return _responseStr;
}

///   <summary>
///   Class1   的摘要说明。
///   </summary>
//   RequestState   类用于通过
//   异步调用传递数据
public class RequestState
{
const int BUFFER_SIZE = 1024;
public StringBuilder RequestData;
public byte[] BufferRead;
public HttpWebRequest Request;
public Stream ResponseStream;
//   创建适当编码类型的解码器
public Decoder StreamDecode = Encoding.Default.GetDecoder();

public RequestState()
{
BufferRead = new byte[BUFFER_SIZE];
RequestData = new StringBuilder(" ");
Request = null;
ResponseStream = null;
}
}

//   ClientGetAsync   发出异步请求
public static ManualResetEvent allDone = new ManualResetEvent(false);
const int BUFFER_SIZE = 1024;
public static void Main(string[] args)
{
//修改或给此字符串作循环,以连续的发送和接受数据流
string HttpUrl = "http://211.154.223.116:3000/tysy.jsp?CorpID=1&Phone=13012345678&Data=17200310101 ";
//   从命令行获取   URI
Uri HttpSite = new Uri(HttpUrl);

//   创建请求对象
HttpWebRequest wreq = (HttpWebRequest)WebRequest.Create(HttpSite);

//   创建状态对象
RequestState rs = new RequestState();

//   将请求添加到状态,以便它可以被来回传递
rs.Request = wreq;

//   发出异步请求
IAsyncResult r = (IAsyncResult)wreq.BeginGetResponse(new AsyncCallback(RespCallback), rs);

//   将   ManualResetEvent   设置为   Wait,
//   以便在调用回调前,应用程序不退出
allDone.WaitOne();
}

private static void RespCallback(IAsyncResult ar)
{
//   从异步结果获取   RequestState   对象
RequestState   rs   =   (RequestState)   ar.AsyncState;

//   从   RequestState   获取   HttpWebRequest  
HttpWebRequest   req   =   rs.Request;

//   调用   EndGetResponse   生成   HttpWebResponse   对象
//   该对象来自上面发出的请求
HttpWebResponse   resp   =   (HttpWebResponse)   req.EndGetResponse(ar);

//   既然我们拥有了响应,就该从
//   响应流开始读取数据了
Stream   ResponseStream   =   resp.GetResponseStream();

//   该读取操作也使用异步完成,所以我们
//   将要以   RequestState   存储流
rs.ResponseStream   =   ResponseStream;

//   请注意,rs.BufferRead   被传入到   BeginRead。
//   这是数据将被读入的位置。
IAsyncResult   iarRead   =   ResponseStream.BeginRead(rs.BufferRead,   0,   BUFFER_SIZE,   new   AsyncCallback(ReadCallBack),   rs);
}

private static void ReadCallBack(IAsyncResult asyncResult)
{
//   从   asyncresult   获取   RequestState   对象
RequestState rs = (RequestState)asyncResult.AsyncState;

//   取出在   RespCallback   中设置的   ResponseStream
Stream responseStream = rs.ResponseStream;

//   此时   rs.BufferRead   中应该有一些数据。
//   读取操作将告诉我们那里是否有数据
int read = responseStream.EndRead(asyncResult);

if (read > 0)
{
//   准备   Char   数组缓冲区,用于向   Unicode   转换
Char[] charBuffer = new Char[BUFFER_SIZE];

//   将字节流转换为   Char   数组,然后转换为字符串
//   len   显示多少字符被转换为   Unicode
int len = rs.StreamDecode.GetChars(rs.BufferRead, 0, read, charBuffer, 0);
String str = new String(charBuffer, 0, len);

//   将最近读取的数据追加到   RequestData   stringbuilder   对象中,
//   该对象包含在   RequestState   中
rs.RequestData.Append(str);

//   现在发出另一个异步调用,读取更多的数据
//   请注意,将不断调用此过程,直到  
//   responseStream.EndRead   返回   -1
IAsyncResult ar = responseStream.BeginRead(rs.BufferRead, 0, BUFFER_SIZE, new AsyncCallback(ReadCallBack), rs);
}
else
{
if (rs.RequestData.Length > 1)
{
//   所有数据都已被读取,因此将其显示到控制台
string strContent;
strContent = rs.RequestData.ToString();

//Console.WriteLine(strContent.Trim().ToString());

string MsgData = "Phone= " + MidStr("phone ", strContent) + "\n " + "Data= " + MidStr("data ", strContent) + "\n " + "Data-Id= " + MidStr("data-id ", strContent);

Console.WriteLine(MsgData.ToString());

//==================================以XML方式处理流时,有问题.所以我把返回值当字符串处理的==============================
// XmlNodeReader   nreader   =   null;
// try
// {
// XmlDocument   exampledoc   =   new   XmlDocument();
// exampledoc.Load(strContent.Trim().ToString());
// XmlNode   name   =   exampledoc.SelectSingleNode
// ( "/csjx-service/data ");     ///单个读取节点值
// if(name!=   null)
// {
// nreader   =   new   XmlNodeReader(name);
// while(nreader.Read())
// {
// Console.Write   (nreader.Value);
// Console.Write   (nreader.Name+ "   ");
// }
// }
// }
// finally
// {
// if(nreader!=null)
// nreader.Close();
// }
}

//   关闭响应流
responseStream.Close();

//   设置   ManualResetEvent,以便主线程可以退出
allDone.Set();
}
return;
}
///   <summary>
///   返回两个字符串节点之间的字符串
///   </summary>
///   <param   name= "NodeStr "> 字符节点 </param>
///   <param   name= "StreamStr "> 数据流 </param>
///   <returns> 返回的提取的字符串 </returns>
public static string MidStr(string NodeStr, string StreamStr)
{
int StarStr = (StreamStr.Trim()).IndexOf(" < " + NodeStr.Trim() + "> ");
int StopStr = (StreamStr.Trim()).IndexOf(" </ " + NodeStr.Trim() + "> ");
string MidStr = (StreamStr.Trim()).Substring(StarStr + NodeStr.Length + 2, StopStr - StarStr - NodeStr.Length - 2);
return MidStr;
}
}

}

时间: 2024-10-06 15:29:41

Socket学习4 文件传输的相关文章

用scala实现一个基于TCP Socket的快速文件传输程序

这是用scala实现的一个简单的文件传输程序. 服务端 package jpush import java.io.{DataInputStream, File, FileOutputStream} import java.net.ServerSocket import scala.collection.JavaConversions._ /** * Created by dingb on 2016/6/3. */ object Server extends App { def port = 88

Linux socket跨局域网聊天和文件传输

一直想写一个跨局域网聊天和文件传输,以及视频聊天的软件,这两天刚好闲着没啥事就把代码写完了,代码已经上传至github:https://github.com/vinllen/chat 其实之前想法P2P模式,P2P的话必须穿透NAT,现在的NAT有4种模式: 完全圆锥型NAT 受限圆锥型NAT 端口受限圆锥型NAT 对称NAT(双向NAT) 维基百科给出的定义如下: 1.Full cone NAT,亦即著名的一对一(one-to-one)NAT 一旦一个内部地址(iAddr:port1)映射到外

linux网络环境下socket套接字编程(UDP文件传输)

今天我们来介绍一下在linux网络环境下使用socket套接字实现两个进程下文件的上传,下载,和退出操作! 在socket套接字编程中,我们当然可以基于TCP的传输协议来进行传输,但是在文件的传输中,如果我们使用TCP传输,会造成传输速度较慢的情况,所以我们在进行文件传输的过程中,最好要使用UDP传输. 在其中,我们需要写两个程序,一个客户端,一个服务端,在一个终端中,先运行服务端,在运行客户端,在服务端和客户端都输入IP地址和端口号,注意服务端和客户端的端口号要相同,然后选择功能,在linux

Java基于Socket文件传输示例(转)

最近需要进行网络传输大文件,于是对基于socket的文件传输作了一个初步的了解.在一位网友提供的程序基础上,俺进行了一些加工,采用了缓冲输入/输出流来包装输出流,再采用数据输入/输出输出流进行包装,加快传输的速度.废话少说,先来看服务器端的程序. 1.服务器端 package sterning; import java.io.BufferedInputStream; import java.io.DataInputStream; import java.io.DataOutputStream;

Android 用Socket实现PC和手机的文件传输

PC服务器端代码: /* * PC与<a href="http://lib.csdn.net/base/android" class='replace_word' title="Android知识库" target='_blank' style='color:#df3434; font-weight:bold;'>Android</a>客户端实现文件的传送 * PC服务器端 */ package com.<a href="ht

socket文件传输功能的实现

服务端: #include <stdio.h> #include <winsock2.h> #pragma comment (lib, "ws2_32.lib")  //加载 ws2_32.dll    #define BUF_SIZE 1024    int main(int argc, char *argv[]){     //先检查文件是否存在     char *filename = "Beyond.mp3";//文件名     FI

C#Socket文件传输(发送与接收代码)

这里是发送的代码: SendVarData是转码后发送函数 1 /// <summary> 2 /// 发送文件 3 /// </summary> 4 /// <param name="userName"></param> 5 private void SendFileToClient(string userName) 6 { 7 User targetUser = userListDict[userName]; 8 String tar

Socket编程一实现简易的聊天功能以及文件传输

干程序是一件枯燥重复的事,每当感到内心浮躁的时候,我就会找小说来看.我从小就喜爱看武侠小说,一直有着武侠梦.从金庸,古龙,梁羽生系列到凤歌(昆仑),孙晓(英雄志)以及萧鼎的(诛仙)让我领略着不一样的江湖. 如果你有好看的武侠系列小说,给我留言哦.题外话就扯这么多了,接着还是上技术. 看看今天实现的功能效果图: 可以这里使用多台手机进行通讯,[凤歌]我采用的服务器发送消息. 是不是只有发送消息,有些显得太单调了.好,在发送消息的基础上增加文件传输.后期会增加视频,音频的传输,增加表情包.那一起来看

Java基于Socket文件传输示例

最近需要进行网络传输大文件,于是对基于socket的文件传输作了一个初步的了解.在一位网友提供的程序基础上,俺进行了一些加工,采用了缓冲输入/输出流来包装输出流,再采用数据输入/输出输出流进行包装,加快传输的速度.废话少说,先来看服务器端的程序. 1.服务器端 package localSocket; import java.io.BufferedInputStream; import java.io.DataInputStream; import java.io.DataOutputStrea