1 应用到com0com,com0com是一个易于使用的内核模式虚拟串行端口驱动程序,以帮助您的工作需要。
命令:install PortNum=COM3 PortNum=COM4
表示建立一个COM3发送数据到COM4的连接。执行命令后会在设备管理器中看到这两个虚拟的串口。
2 分为两个代码文件
A -- client -- com.c : A机器将读取串口数据,然后用TCP连接发送到B机器
B -- remote_machine.c: B机器接收A传送来的数据,就好像B机器能直接读取A机器的串口一样。
3 串口通信
COM3:用串口调试工具 发送数据
COM4:用C程序监听此串口,读取数据
4 TCP
A机器:作为client端,连接远程机器B
B机器:作为server端
5 附上源代码
A -- client -- com.c :
#include<stdio.h> #include<windows.h> #include<stdlib.h> #include<WINSOCK2.H> struct COMMTIMEOUTS { DWORD ReadIntervalTimeout; DWORD ReadTotalTimeoutMultiplier; DWORD ReadTotalTimeoutConstant; DWORD WriteTotalTimeoutMultiplier; DWORD WriteTotalTimeoutConstant; }; HANDLE m_hIDComDev;///////////////打开串口 句柄 int delay = 5; /*********************************************************************************************** initialSerial 功能:串口初始化 ***********************************************************************************************/ void initialSerial() //串口初始化 { char szComParams[50]; DCB dcb; char *m_com; char *m_baud; char *m_jiaoyan; m_com="Com4"; m_baud="1200"; m_jiaoyan="E"; COMMTIMEOUTS CommTimeOuts; m_hIDComDev = NULL; m_hIDComDev = CreateFile(m_com, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); //打开串口 if(m_hIDComDev==INVALID_HANDLE_VALUE) { printf("打开串口错误0,请检查!"); goto endd; } if(m_hIDComDev ==(HANDLE) -1) { printf("打开串口错误,请检查!"); goto endd; } SetCommTimeouts(m_hIDComDev, &CommTimeOuts); //串口超时配置 CommTimeOuts. ReadIntervalTimeout= 0xFFFFFFFF;//"0xFFFFFFFF"; CommTimeOuts. ReadTotalTimeoutMultiplier = 0; CommTimeOuts. ReadTotalTimeoutConstant =5000; CommTimeOuts. WriteTotalTimeoutMultiplier = 0; CommTimeOuts. WriteTotalTimeoutConstant = 5000; PurgeComm(m_hIDComDev, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR ) ; m_com="Com4:38400,E,8,1"; wsprintf(szComParams, m_com); //设置串口参数 dcb. DCBlength = sizeof(DCB); GetCommState(m_hIDComDev, &dcb);// int baud; baud = atoi(m_baud); dcb. BaudRate = baud; //设置波特率 dcb. ByteSize= 8; //设置校验字节 if ((!SetCommState(m_hIDComDev, &dcb))||(!SetupComm(m_hIDComDev,10000,10000)))//设置串口和收发缓冲器的大小 { DWORD dwError = GetLastError(); CloseHandle(m_hIDComDev); } PurgeComm(m_hIDComDev,PURGE_RXCLEAR|PURGE_TXCLEAR|PURGE_TXABORT|PURGE_RXABORT);//清收发缓冲器 endd: ; } /************************************************************************************************ SendData 功能:发送数据给串口 ************************************************************************************************/ DWORD SendData( unsigned char buff[],int send_length) //发送数据 { int t; DWORD dwBytesWritten; if(!WriteFile(m_hIDComDev,buff,send_length,&dwBytesWritten,NULL)) { return 0; } for (t=0;t<send_length;t++) fprintf(stdout," %2X ",buff[t]); printf("\n"); PurgeComm(m_hIDComDev,PURGE_TXCLEAR); //清发送缓冲区 return 1; } /*********************************************************************************************** ReadData 功能:从串口读取数据 参数:rebuff 收到的数据 dwBytesRead 要收到的长度 delay 延时 ***********************************************************************************************/ DWORD ReadData(unsigned char rebuff [],DWORD dwBytesRead ) //读取数据 { DWORD dwErrorFlags; COMSTAT stat; if(delay>0) ClearCommError(m_hIDComDev,&dwErrorFlags,&stat); if(stat.cbInQue <= 0) //"stat.cbInQue" is bytes in input buffer return 0; dwBytesRead = min(dwBytesRead,(DWORD)stat.cbInQue); //获取字符个数 if(!ReadFile(m_hIDComDev,rebuff,dwBytesRead,&dwBytesRead,NULL)) //整体读入 { return 0; } return dwBytesRead; } void tcpSend(unsigned char ch[]) { int err; char receiveBuf[100]={"0"}; char ip_addr[16]; WORD versionRequired; WSADATA wsaData; versionRequired=MAKEWORD(1,1); err=WSAStartup(versionRequired,&wsaData); SOCKET clientSocket; SOCKADDR_IN clientsock_in; if (err) { return; } clientSocket=socket(AF_INET,SOCK_STREAM,0); clientsock_in.sin_addr.S_un.S_addr=inet_addr("127.0.0.1"); clientsock_in.sin_family=AF_INET; clientsock_in.sin_port=htons(6000); connect(clientSocket,(SOCKADDR*)&clientsock_in,sizeof(SOCKADDR)); recv(clientSocket,receiveBuf,101,0); //printf("%s\n",ch); send(clientSocket,ch,101,0);//应用TCP连接发送串口数据 } void comRead(unsigned char ch1[]) { int send_length = 100; // 接收的长度 printf("begin\n"); initialSerial(); printf("init end.\n"); printf("begin send.\n"); /*r = SendData(ch,send_length); if(r) printf("send end.\n"); else printf("error\n");*/ DWORD x ; while(1) { x = ReadData(ch1,send_length); sleep(1); printf("waiting for data...\n"); if(x) break; } } main() { int i,r; unsigned char ch[10] = "hello"; unsigned char ch1[100] = "\0"; comRead(ch1);//读取 串口数据 到 ch1 数组 printf("\n\n\n\n"); printf("Machine A...\n\n接收本机串口数据中...\n"); printf("接收数据显示:%s\n",ch1); printf("发送至MachineB中...\n"); tcpSend(ch1); // 将串口数据发送到 远程机器 printf("end.\n"); system("pause"); }
B -- remote_machine.c:
#include<stdio.h> #include<windows.h> #include<stdlib.h> #include <WINSOCK2.H> int main() { SOCKADDR_IN clientsocket; SOCKET serConn; WORD myVersionRequest; WSADATA wsaData; myVersionRequest=MAKEWORD(1,1); int err; int len=sizeof(SOCKADDR); err=WSAStartup(myVersionRequest,&wsaData); if (err) { return -1; } SOCKET serSocket=socket(AF_INET,SOCK_STREAM,0); SOCKADDR_IN addr; addr.sin_family=AF_INET; addr.sin_addr.S_un.S_addr=htonl(INADDR_ANY); addr.sin_port=htons(6000); bind(serSocket,(SOCKADDR*)&addr,sizeof(SOCKADDR)); listen(serSocket,5); printf("Machine B...\n识别Machine A机器的串口...\n接收数据中...\n"); char sendBuf[50]; serConn=accept(serSocket,(SOCKADDR*)&clientsocket,&len); sprintf(sendBuf,"welcome!",inet_ntoa(clientsocket.sin_addr)); send(serConn,sendBuf,strlen(sendBuf)+1,0); char recvBuf[100]; recv(serConn,recvBuf,101,0); printf("接收成功\n\n数据显示:%s\n",recvBuf); system("pause"); return 0; }
主要用于自己记录,当然也希望能帮组有需要的同学。