winform 怎么发送文件给GPRS模块
winform 怎么发送文件给GPRS模块,求各位大侠帮帮忙,我刚接触GPRS通信,TCP协议一定要三次握手么?
[解决办法]
你们有没有服务器?如果有那就好说一些了,pc和gprs模块都通过socket接入服务器,通过服务器中转传输。MC52iR3带有tcp/ip协议栈,可以直接使用模块的socket方面的AT指令。
如果没有服务器,那就要分析pc端的网络接入方式,如果是adsl那么可以实现pc端与gprs模块直接建立socket连接来传输,传输前需要通过短信把pc端的动态公网地址通知gprs模块。
如果是那种小区宽带,就有两个选择,前提条件是pc端也要连接一个gprs模块:
一是租一个网站空间,将文件上传到网站后短信通知gprs模块,gprs模块从网站下载;
二是利用gprs模块的数据数功能(类似传真那样的,可能需要移动网络运行商开通),这一块没做过不太了解。
[解决办法]
这样的程序说大不大说小不小,socket服务器要做到性能与可靠性的完善不是一蹴而就的,我给你贴一个我这里的socket服务器类,仅供借鉴。你最好花更多的时间查阅msdn来完善这方面的知识。
第一部分:
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Net.Sockets;using System.Net;using System.Threading;using System.Runtime.InteropServices;namespace nsqserver{ [StructLayout(LayoutKind.Sequential)] public struct SendSegment { byte[] sendbuffer; SendPacketsElement[] sendelements; int offset; int count; public SendSegment(SendPacketsElement[] elements) { sendelements = elements; sendbuffer = null; offset = 0; count = 0; } public SendSegment(byte[] buffer, int ost, int cot) { sendbuffer = buffer; sendelements = null; offset = ost; count = cot; } public byte[] SendBuffer { get { return this.sendbuffer; } } public SendPacketsElement[] SendElments { get { return this.sendelements; } } public int Offset { get { return this.offset; } } public int Count { get { return this.count; } } } public enum RecvHasHeaders { On, Off } class SocketServer { byte[] buffers; byte[] sendbuffer; Socket[] sockets; SocketAsyncEventArgs[] sendargs; SocketAsyncEventArgs[] recvargs; SocketAsyncEventArgs[] acepargs; Queue<SendSegment>[] queues; Object[] objs; int recvbufferlen; int sockcount; int sendbufferlen; int sendindex; Object stackobj = new Object(); RecvHasHeaders[] recvhasheader; Socket acceptsock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); public event Func<int, byte[], int, int, int> RecvByteComplete; public event Func<int, byte[], int, int, int> RecvNoHeaderComplete; public event Action<int> SendPacketsComplete; public event Action<int> AcceptComplete; public event Action<int> SendComplete; public event Action<int> CloseComplete; byte[] inValue = new byte[] { 1, 0, 0, 0, 0x88, 0x13, 0, 0, 0x88, 0x13, 0, 0 }; public SocketServer(int skcount, int rvbufferlen, int sdbufferlen, int queuecount, string ipadr, int port) { buffers = new byte[skcount * rvbufferlen]; sendbufferlen = sdbufferlen; sendindex = 0; sendbuffer = new byte[sdbufferlen]; sockets = new Socket[skcount]; sendargs = new SocketAsyncEventArgs[skcount]; recvargs = new SocketAsyncEventArgs[skcount]; acepargs = new SocketAsyncEventArgs[skcount]; queues = new Queue<SendSegment>[skcount]; objs = new Object[skcount]; recvhasheader = new RecvHasHeaders[skcount]; recvbufferlen = rvbufferlen; sockcount = skcount; acceptsock.Bind(new IPEndPoint(IPAddress.Parse(ipadr), port)); acceptsock.Listen(100); for (int i = 0; i < skcount; i++) { sockets[i] = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); sendargs[i] = new SocketAsyncEventArgs(); sendargs[i].UserToken = i; recvargs[i] = new SocketAsyncEventArgs(); recvargs[i].UserToken = i; acepargs[i] = new SocketAsyncEventArgs(); acepargs[i].AcceptSocket = sockets[i]; acepargs[i].UserToken = i; queues[i] = new Queue<SendSegment>(queuecount); objs[i] = new Object(); recvhasheader[i] = RecvHasHeaders.On; recvargs[i].SetBuffer(buffers, i * rvbufferlen, 4); recvargs[i].Completed += new EventHandler<SocketAsyncEventArgs>(Receive_Completed); sendargs[i].Completed += new EventHandler<SocketAsyncEventArgs>(Send_Completed); acepargs[i].Completed += new EventHandler<SocketAsyncEventArgs>(Server_Completed); } } public void Sethnheader(int sockindx, RecvHasHeaders rh) { recvhasheader[sockindx] = rh; } public void startaccept() { for (int i = 0; i < sockcount; i++) acceptsock.AcceptAsync(acepargs[i]); } void Server_Completed(object sender, SocketAsyncEventArgs e) { int asockindx = (int)e.UserToken; if (e.SocketError != SocketError.Success) { disconnectsocket(asockindx); return; } if (e.LastOperation == SocketAsyncOperation.Accept) { if (AcceptComplete != null) AcceptComplete.Invoke(asockindx); sockets[asockindx].IOControl(IOControlCode.KeepAliveValues, inValue, null); sockets[asockindx].ReceiveAsync(recvargs[asockindx]); return; } if (e.LastOperation == SocketAsyncOperation.Disconnect) { e.SetBuffer(null, 0, 0); acceptsock.AcceptAsync(e); return; } }
[解决办法]
第三部分:
unsafe public SendSegment xuliehua(object[] objs, bool usepool) { int len = 0; int* tps = stackalloc int[objs.Length]; for (int i = 0; i < objs.Length; i++) { if (objs[i] == null) { tps[i] = 5; len += 4; continue; } Type t = objs[i].GetType(); if (t == typeof(int)) { tps[i] = 1; len += 8; } else if (t == typeof(string)) { tps[i] = 2; len += 8 + ((string)objs[i]).Length * 2; } else if (t == typeof(double)) { tps[i] = 3; len += 12; } else if (t == typeof(DateTime)) { tps[i] = 4; len += 8; } else if (t == typeof(bool)) { tps[i] = 6; len += 8; } else { tps[i] = 7; len += 4; } } len += 4; if (len > recvbufferlen) throw new ArgumentException("发送长度超出缓冲区长度"); byte[] bf; int bindx = 0; if (usepool) { bf = sendbuffer; bindx = getsendindex(len); } else bf = new byte[len]; fixed (byte* p = bf) { *(int*)(p + bindx) = len; } bindx += 4; for (int i = 0; i < objs.Length; i++) { int tp = tps[i]; if (tp <= 0 || tp > 7) { throw new ArgumentException("序列化时参数类型超出规定范围"); } fixed (byte* p = bf) { *(int*)(p + bindx) = tp; } bindx += 4; if (tp == 1) { fixed (byte* p = bf) { *(int*)(p + bindx) = (int)objs[i]; } bindx += 4; } else if (tp == 2) { string s = (string)objs[i]; fixed (byte* p = bf) { *(int*)(p + bindx) = s.Length * 2; } bindx += 4; Encoding.Unicode.GetBytes(s, 0, s.Length, bf, bindx); bindx += s.Length * 2; } else if (tp == 3) { fixed (byte* p = bf) { *(double*)(p + bindx) = (double)objs[i]; } bindx += 8; } else if (tp == 4) { fixed (byte* p = bf) { *(uint*)(p + bindx) = Dttoint.toint((DateTime)objs[i]); } bindx += 4; } else if (tp == 6) { fixed (byte* p = bf) { *(bool*)(p + bindx) = (bool)objs[i]; } bindx += 4; } } return new SendSegment(bf, bindx - len, len); } public object[] fanxulie(byte[] sbuffer, int startindex, int count) { int index = startindex; int endindex = startindex + count; int len = 0; while (index < endindex) { int tp = BitConverter.ToInt32(sbuffer, index); if (tp <= 0 || tp > 7) throw new ArgumentException("反序列化时参数类型超出规定范围"); index += 4; if (tp == 1 || tp == 4 || tp == 6) index += 4; else if (tp == 2) { int strlen = BitConverter.ToInt32(sbuffer, index); index += 4; if (strlen < 0 || strlen > startindex + count - index) throw new ArgumentException("反序列化时字符串长度超出缓冲区"); index += strlen; } else if (tp == 3) index += 8; len++; } object[] neirong = new object[len]; index = startindex; len = 0; while (index < endindex) { int tp = BitConverter.ToInt32(sbuffer, index); index += 4; if (tp == 1) { neirong[len] = BitConverter.ToInt32(sbuffer, index); index += 4; } else if (tp == 2) { int strlen = BitConverter.ToInt32(sbuffer, index); index += 4; neirong[len] = Encoding.Unicode.GetString(sbuffer, index, strlen); index += strlen; } else if (tp == 3) { neirong[len] = BitConverter.ToDouble(sbuffer, index); index += 8; } else if (tp == 4) { neirong[len] = Dttoint.todt(BitConverter.ToUInt32(sbuffer, index)); index += 4; } else if (tp == 6) { neirong[len] = BitConverter.ToBoolean(sbuffer, index); index += 4; } else neirong[len] = null; len++; } return neirong; } int getsendindex(int len) { int index = (int)(((uint)Interlocked.Add(ref sendindex, len)) % sendbufferlen); if (index - len < 0) index = (int)(((uint)Interlocked.Add(ref sendindex, len)) % sendbufferlen); return index - len; } }}
[解决办法]
那你看,你现在是从互联网上下载数据,不是上传数据。
你发送联网的at命令到gprs模块,如果gprs给你返回OK,那就表示连接成功。
你把你要下载的文件放到互联网上,从网上下载数据的代码,给你下了下,如果你也是C#的话,应该没有问题的了。
try
{
System.Net.WebRequest wr = System.Net.WebRequest.Create("http://www.hongname.com/mxtp/z/good/zhangmy3/004.jpg");
wr.Credentials = CredentialCache.DefaultCredentials;
WebResponse wrp;
wrp = wr.GetResponse();
System.IO.Stream stream = wrp.GetResponseStream();
long count = wrp.ContentLength;
int curr = 0;
byte[] bdata = new byte[count];
do
{
curr += stream.Read(bdata, curr, bdata.Length - curr);
} while (curr < count);
System.IO.FileStream fs = new System.IO.FileStream("C:\\a.bin", System.IO.FileMode.OpenOrCreate);
fs.Write(bdata, 0, bdata.Length);
fs.Flush();
stream.Close();
fs.Close();
}
catch(Exception Ex) { }