想玩玩通过串口连接手机发短信。查了各种资料现在可以通超级终端连接手机并成功发送短信。
但通过超级终端实在是麻烦,想通过C#做一个简单程序来操作,研究了一天也没成功进行串口通迅。
那位大虾有C#串口操作的经验,请给帮个忙。
请最好给出源码。

解决方案 »

  1.   

    用MsComm或CommBase
    英文水平不差的直接看这个:
    http://msdn.microsoft.com/msdnmag/issues/02/10/NETSerialComm/default.aspx
    自认为英文水平差就用MsComm(即以前的VC或VB带有的那个MsComm32.OCX)
      

  2.   

    MsComm32.OCX需要注册,网上有关与手工注册的方法,但我用了一下不行注册不了。
    CommBase 我上http://msdn.microsoft.com/msdnmag/issues/02/10/NETSerialComm/default.aspx看了一下,也试着用了,可以打开端口,但写端口失败。
      

  3.   

    第一:通过MSCOMM控件这是最简单的,最方便的方法。可功能上很难做到控制自如,同时这个控件并不是系统本身所带,所以还得注册,不在本文讨论范围。可以访问http://www.devhood.com/tutorials/tutorial_details.aspx?tutorial_id=320 ,一个国外网友的写的教程,作者很热心,我曾有发邮件给他,很快就回复了。  第二:微软在.NET新推出了一个串口控件,基于.NET的P/Invoke调用方法实现,详细的大家可以访问微软网站http://msdn.microsoft.com/msdnmag/issues/02/10/NETSerialComm/default.aspx,方便得到更多资料。  第三:就是用第三方控件啦,可一般都要付费的,不太合实际,不作考虑  第四:自己用API写串口通信,这样难度高点,但对于我们来说,可以方便实现自己想要的各种功能
      

  4.   

    using System; 
    using System.Runtime.InteropServices; /// <summary> 
    /// (C)2003-2005 C2217 Studio 保留所有权利 
    /// 
    /// 文件名称: IbmsSerialPort.cs 
    /// 文件ID: 
    /// 文件说明: 
    /// 封装动态链接库IbmsSerialPort.dll的功能,提供在.NET环境中 
    /// 串口异步接收和发送数据的功能。 
    /// 
    /// 当前版本: 1.0 
    /// 
    /// 作者: 邓杨均 
    /// 创建日期: 2005-2-2 
    /// 最后修改日期: 2005-2-2 
    /// 
    /// 历史修改记录: 
    /// 
    /// </summary> 
    namespace Ibms.Tool.IO 
    { /// <summary> 
    /// 当串口接收到数据时,会产生一个事件。 
    /// SPRecvDataArgs就是该事件的参数,参数中的RecvData包含接收到的数据。 
    /// 使用方法: 
    /// </summary> 
    public class SPRecvDataArgs:EventArgs 

    /// <summary> 
    /// 接收到的数据组成的字节数组 
    /// </summary> 
    private byte[] recvData; /// <summary> 
    /// 构造函数,需要一个包含数据的byte[]作为初始化参数来实例化 SPRecvDataArgs 
    /// </summary> 
    /// <param name="recvData">接收到的数据</param> 
    public SPRecvDataArgs(byte[] recvData) 

    if( recvData == null) 

    throw(new ArgumentNullException()); 
    } this.recvData = recvData; 
    } /// <summary> 
    /// 返回接收到的数据内容 
    /// </summary> 
    public byte[] RecvData 

    get 

    return recvData; 



    /// <summary> 
    /// 封装动态链接库IbmsSerialPort.dll的功能,提供在.NET环境中异步 
    /// 串口接收和发送功能。特别实现的是异步通过信号自动接收数据的模式。 
    /// </summary> 
    public class IbmsSerialPort:IDisposable 
    { #region 平台调用声明代码 /// <summary> 
    /// 声明IbmsSerialPort.dll的Ibms_OpenPort函数 
    /// </summary> 
    /// <param name="nPort">串口号</param> 
    /// <param name="nRate">波特率</param> 
    /// <returns></returns> 
    [DllImport("IbmsSerialPort.dll")] 
    public static extern IntPtr Ibms_OpenPort(int nPort, int nRate); /// <summary> 
    /// 声明IbmsSerialPort.dll的Ibms_Close函数 
    /// </summary> 
    [DllImport("IbmsSerialPort.dll")] 
    public static extern void Ibms_Close( IntPtr port); /// <summary> 
    /// 声明IbmsSerialPort.dll的Ibms_SendData函数 
    /// </summary> 
    /// <param name="data"></param> 
    /// <param name="nDataSize"></param> 
    /// <returns></returns> 
    [DllImport("IbmsSerialPort.dll")] 
    public static extern bool Ibms_SendData( IntPtr port, byte[] data,int nDataSize); /// <summary> 
    /// 声明IbmsSerialPort.dll的Ibms_SetFuncHandle函数 
    /// </summary> 
    /// <param name="handDataFunc"></param> 
    [DllImport("IbmsSerialPort.dll")] 
    public static extern void Ibms_SetFuncHandle( IntPtr port, HandleFunc handDataFunc); #endregion #region 定义字段 /// <summary> 
    /// 定义数据处理委托,作为API的函数指针传入动态链接库 
    /// </summary> 
    public delegate void HandleFunc(IntPtr pData, int nDataSize); /// <summary> 
    /// 定义数据接收事件的原型 
    /// </summary> 
    public delegate void RecvData(object sender,SPRecvDataArgs e); /// <summary> 
    /// 定义数据接收事件 
    /// </summary> 
    public event RecvData OnRecvData; /// <summary> 
    /// 串口处理接收数据的委托 
    /// </summary> 
    private HandleFunc _handleDataFunc; /// <summary> 
    /// 串口的编号,从1开始的整数,最大255 
    /// </summary> 
    private int port; /// <summary> 
    /// 串口所支持的波特率,必须是标准波特率之一 
    /// </summary> 
    private StanderdRate rate; /// <summary> 
    /// 串口当前的打开状态 
    /// </summary> 
    private bool openStatus=false; /// <summary> 
    /// 串口句柄 
    /// </summary> 
    private IntPtr portHandle; #region 定义标准的串口波特率 /// <summary> 
    /// 标准的波特率 
    /// </summary> 
    public enum StanderdRate 

    R50=50, 
    R75=75, 
    R110=110, 
    R150=150, 
    R300=300, 
    R600=600, 
    R1200=1200, 
    R2400=2400, 
    R4800=4800, 
    R9600=9600, 
    R19200=19200, 
    R38400=38400, 
    R57600=57600, 
    R76800=76800, 
    R115200=115200 
    }; #endregion #endregion #region 定义方法 /// <summary> 
    /// 构造函数 
    /// </summary> 
    public IbmsSerialPort() 

    portHandle = (IntPtr)0; _handleDataFunc = new HandleFunc(OnDllRecvData); 
    } /// <summary> 
    /// 打开串口 
    /// </summary> 
    /// <param name="nPort">串口号</param> 
    /// <param name="nRate">波特率</param> 
    /// /// <exception cref="ApplicationException">抛出应用程序异常,包换错误描述</exception> 
    public void Open(int nPort, StanderdRate nRate) 
    { if(nPort > 255 || nPort < 0) 

    throw(new ArgumentOutOfRangeException()); 
    } port = nPort; 
    rate = nRate; portHandle = Ibms_OpenPort( port, (int)rate ); if( (IntPtr)0 == portHandle ) 

    throw( new ApplicationException("打开串口失败")); 
    } //注册函数指针 
    Ibms_SetFuncHandle( portHandle, _handleDataFunc ); openStatus = true; } 
    /// <summary> 
    /// 关闭串口 
    /// </summary> 
    public void Close() 

    if( openStatus ) 

    Ibms_Close( portHandle); } openStatus = false; } 
    /// <summary> 
    /// 发送数据 
    /// </summary> 
    /// <param name="sendData">数据内容</param> 
    /// <exception cref="ApplicationException">抛出应用程序异常,包换错误描述</exception> 
    public void SendData( byte[] data ) 

    if( !openStatus ) 

    throw( new ApplicationException("串口没有打开,发送数据失败") ); 
    } if( !Ibms_SendData( portHandle, data, data.Length ) ) 

    throw( new ApplicationException("串口发送数据失败") ); 

    } /// <summary> 
    /// 处理接收到的串口数据 
    /// </summary> 
    /// <param name="pData">串口数据接收缓冲区首地址</param> 
    /// <param name="nDataSize">数据大小,一般数据大小不超过2K</param> 
    unsafe protected void OnDllRecvData(IntPtr pUnhandleData, int nDataSize) 

    int dataSize= nDataSize ; byte * pData =(byte *) pUnhandleData; byte[] data = new byte[dataSize]; //复制数据到byte数组 
    for(int i=0; i<dataSize; i++) 

    data[i]= pData[i]; 
    } //激发事件 
    OnRecvData( this, new SPRecvDataArgs(data) ); } 
    #endregion #region 定义属性 /// <summary> 
    /// 返回当前的串口号 
    /// </summary> 
    public int Port 

    get 

    return port; 

    } /// <summary> 
    /// 返回当前串口的波特率 
    /// </summary> 
    public StanderdRate Rate 

    get 

    return rate; 

    } /// <summary> 
    /// 返回当前串口的状态 
    /// </summary> 
    public bool OpenStatus 

    get 

    return openStatus; 


    #endregion 
    #region 非托管资源的及时释放 /// <summary> 
    /// 因为包含了非托管的资源(占用系统串口),必须实现IDisposable接口 
    /// 在使用完该类的时候,必须记得调用Dispose(),回收系统资源 
    /// <example> 
    /// 
    /// 方法1 
    /// { 
    /// SerialPort port =new SerialPort(); 
    /// ... 
    /// //在try-catch-finaly的finaly中释放资源 
    /// 
    /// port.Dispose(); 
    /// } 
    /// 
    /// 方法2 
    /// using( SerialPort port = new SerialPort()) 
    /// { 
    /// ... 
    /// } 
    /// 变量超出作用域时会自动调用其Dispose()方法 
    /// 
    /// </example> 
    /// </summary> ~IbmsSerialPort() 

    Dispose( false ); 
    } protected virtual void Dispose( bool disposing ) 

    if( disposing ) 

    //清理托管的对象 
    } //清理非托管的资源 
    Close(); 

    #region IDisposable 成员 public void Dispose() 

    // TODO: 添加 SerialPort.Dispose 实现 
    Dispose( true ); GC.SuppressFinalize(this); 
    } #endregion 
    #endregion } } 
      

  5.   

    去网上找JustinIO.cs的代码既可
      

  6.   

    代码太长,贴不下来,不过我感觉这个可能是.net下做得最好的,下载地址为:www.codeworks.it/net/index.htm也可以找我
      

  7.   

    我找到了JustinIO.cs的代码,但还是可以打开端口却写端口失败!
    以下是JustinIO.cs的代码,与大家共享。内容太长所以分开贴出。
    第一部分:using System; 
    using System.Runtime.InteropServices; 
    namespace JustinIO 

    public class CommPort 

    public int PortNum =1; 
    public int BaudRate = 9600; 
    public byte ByteSize = 8; 
    public byte Parity=1; // 0-4=no,odd,even,,space 
    public byte StopBits=1; // 0,1,2 = 1, 1.5, 2 
    public int ReadTimeout=2000; 
    //comm port win32 file handle 
    private int hComm = -1; 
    public bool Opened = false; 
    //win32 api constants 
    private const uint GENERIC_READ = 0x80000000; 
    private const uint GENERIC_WRITE = 0x40000000; 
    private const int OPEN_EXISTING = 3;      
    private const int INVALID_HANDLE_VALUE = -1; 
    [StructLayout(LayoutKind.Sequential)] 
    private struct DCB 

    //taken from c struct in platform sdk 
    public int DCBlength;           // sizeof(DCB) 
    public int BaudRate;            // current baud rate 
    public int fBinary;          // binary mode, no EOF check 
    public int fParity;          // enable parity checking 
    public int fOutxCtsFlow;      // CTS output flow control 
    public int fOutxDsrFlow;      // DSR output flow control 
    public int fDtrControl;       // DTR flow control type 
    public int fDsrSensitivity;   // DSR sensitivity 
    public int fTXContinueOnXoff; // XOFF continues Tx 
    public int fOutX;          // XON/XOFF out flow control 
    public int fInX;           // XON/XOFF in flow control 
    public int fErrorChar;     // enable error replacement 
    public int fNull;          // enable null stripping 
    public int fRtsControl;     // RTS flow control 
    public int fAbortOnError;   // abort on error 
    public int fDummy2;        // reserved 
    public ushort wReserved;          // not currently used 
    public ushort XonLim;             // transmit XON threshold 
    public ushort XoffLim;            // transmit XOFF threshold 
    public byte ByteSize;           // number of bits/byte, 4-8 
    public byte Parity;             // 0-4=no,odd,even,,space 
    public byte StopBits;           // 0,1,2 = 1, 1.5, 2 
    public char XonChar;            // Tx and Rx XON character 
    public char XoffChar;           // Tx and Rx XOFF character 
    public char ErrorChar;          // error replacement character 
    public char EofChar;            // end of input character 
    public char EvtChar;            // received event character 
    public ushort wReserved1;         // reserved; do not use 
    }  [StructLayout(LayoutKind.Sequential)] 
    private struct COMMTIMEOUTS 
    {  
    public int ReadIntervalTimeout; 
    public int ReadTotalTimeoutMultiplier; 
    public int ReadTotalTimeoutConstant; 
    public int WriteTotalTimeoutMultiplier; 
    public int WriteTotalTimeoutConstant; 
    }    [StructLayout(LayoutKind.Sequential)]   
    private struct OVERLAPPED 

    public int  Internal; 
    public int  InternalHigh; 
    public int  Offset; 
    public int  OffsetHigh; 
    public int hEvent; 
    }  
      

  8.   

    第二部分:
    [DllImport("kernel32.dll")]
    private static extern int CreateFile( 
    string lpFileName,                         // file name 
    uint dwDesiredAccess,                      // access mode 
    int dwShareMode,                          // share mode 
    int lpSecurityAttributes, // SD 
    int dwCreationDisposition,                // how to create 
    int dwFlagsAndAttributes,                 // file attributes 
    int hTemplateFile                        // handle to template file 
    );  [DllImport("kernel32.dll")] 
    private static extern bool GetCommState( 
    int hFile,  // handle to communications device 
    ref DCB lpDCB    // device-control block 
    );   [DllImport("kernel32.dll")] 
    private static extern bool BuildCommDCB( 
    string lpDef,  // device-control string 
    ref DCB lpDCB     // device-control block 
    );  [DllImport("kernel32.dll")] 
    private static extern bool SetCommState( 
    int hFile,  // handle to communications device 
    ref DCB lpDCB    // device-control block 
    );  [DllImport("kernel32.dll")] 
    private static extern bool GetCommTimeouts( 
    int hFile,                  // handle to comm device 
    ref COMMTIMEOUTS lpCommTimeouts  // time-out values 
    );   [DllImport("kernel32.dll")]    
    private static extern bool SetCommTimeouts( 
    int hFile,                  // handle to comm device 
    ref COMMTIMEOUTS lpCommTimeouts  // time-out values 
    );  [DllImport("kernel32.dll")] 
    private static extern bool ReadFile( 
    int hFile,                // handle to file 
    byte[] lpBuffer,             // data buffer 
    int nNumberOfBytesToRead,  // number of bytes to read 
    ref int lpNumberOfBytesRead, // number of bytes read 
    ref OVERLAPPED lpOverlapped    // overlapped buffer 
    );  [DllImport("kernel32.dll")]    
    private static extern bool WriteFile( 
    int hFile,                    // handle to file 
    byte[] lpBuffer,                // data buffer 
    int nNumberOfBytesToWrite,     // number of bytes to write 
    ref int lpNumberOfBytesWritten,  // number of bytes written 
    ref OVERLAPPED lpOverlapped        // overlapped buffer 
    );  [DllImport("kernel32.dll")] 
    private static extern bool CloseHandle( 
    int hObject   // handle to object 
    );  public void Open() 

    DCB dcbCommPort = new DCB(); 
    COMMTIMEOUTS ctoCommPort = new COMMTIMEOUTS(); 
    // OPEN THE COMM PORT. 
    hComm = CreateFile("LPT" + PortNum ,GENERIC_READ | GENERIC_WRITE,0, 0,OPEN_EXISTING,0,0); 
    // IF THE PORT CANNOT BE OPENED, BAIL OUT. 
    if(hComm == INVALID_HANDLE_VALUE) 

    throw(new ApplicationException("LPT Port Can Not Be Opened")); 

    // SET THE COMM TIMEOUTS. 
    GetCommTimeouts(hComm,ref ctoCommPort); 
    ctoCommPort.ReadTotalTimeoutConstant = ReadTimeout; 
    ctoCommPort.ReadTotalTimeoutMultiplier = 0; 
    ctoCommPort.WriteTotalTimeoutMultiplier = 0; 
    ctoCommPort.WriteTotalTimeoutConstant = 0;  
    SetCommTimeouts(hComm,ref ctoCommPort); 
    // SET BAUD RATE, PARITY, WORD SIZE, AND STOP BITS. 
    // THERE ARE OTHER WAYS OF DOING SETTING THESE BUT THIS IS THE EASIEST. 
    // IF YOU WANT TO LATER ADD CODE FOR OTHER BAUD RATES, REMEMBER 
    // THAT THE ARGUMENT FOR BuildCommDCB MUST BE A POINTER TO A STRING. 
    // ALSO NOTE THAT BuildCommDCB() DEFAULTS TO NO HANDSHAKING. 
    dcbCommPort.DCBlength = Marshal.SizeOf(dcbCommPort); 
    GetCommState(hComm, ref dcbCommPort); 
    dcbCommPort.BaudRate=BaudRate; 
    dcbCommPort.Parity=Parity; 
    dcbCommPort.ByteSize=ByteSize; 
    dcbCommPort.StopBits=StopBits; 
    SetCommState(hComm, ref dcbCommPort); 
    Opened = true; 
    }  public void Close() 

    if (hComm!=INVALID_HANDLE_VALUE) 

    CloseHandle(hComm); 

    }   public byte[] Read(int NumBytes) 

    byte[] BufBytes; 
    byte[] OutBytes; 
    BufBytes = new byte[NumBytes]; 
    if (hComm!=INVALID_HANDLE_VALUE) 

    OVERLAPPED ovlCommPort = new OVERLAPPED(); 
    int BytesRead=0; 
    ReadFile(hComm,BufBytes,NumBytes,ref BytesRead,ref ovlCommPort); 
    OutBytes = new byte[BytesRead]; 
    Array.Copy(BufBytes,OutBytes,BytesRead); 

    else 

    throw(new ApplicationException("Comm Port Not Open")); 

    return OutBytes; 
    }  public void Write(byte[] WriteBytes) 

    if (hComm!=INVALID_HANDLE_VALUE) 

    OVERLAPPED ovlCommPort = new OVERLAPPED(); 
    int BytesWritten = 0; 
    WriteFile(hComm,WriteBytes,WriteBytes.Length,ref BytesWritten,ref ovlCommPort); 

    else 

    throw(new ApplicationException("Comm Port Not Open")); 
    }        

    }  class HexCon 

    //converter hex string to byte and byte to hex string 
    public static string ByteToString(byte[] InBytes) 

    string StringOut=""; 
    foreach (byte InByte in InBytes) 

    StringOut=StringOut + String.Format("{0:X2} ",InByte); 

    return StringOut; 
    }  public static byte[] StringToByte(string InString) 

    string[] ByteStrings; 
    ByteStrings = InString.Split(" ".ToCharArray()); 
    byte[] ByteOut; 
    ByteOut = new byte[ByteStrings.Length-1]; 
    for (int i = 0;i==ByteStrings.Length-1;i++) 

    ByteOut[i] = Byte.Parse("0x" + ByteStrings[i]); 

    return ByteOut; 



      

  9.   

    请问:ekin7913046(终结者)
    在哪里可以下到"IbmsSerialPort.dll".
    这个DLL应该不是提供在.NET环境中的,我的机器装有VS.net 2003我做了个整机搜索也找不到这个文件。
      

  10.   

    用微软的类吧 (NETSerialComm),继承它就可以了。多简单!!也是用API写的也有原代码,你不需要研究明白他,只需要继承他就可以用了!!!性能还不错。安全性非常高!!