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; }
主要用於自己記錄,當然也希望能幫組有需要的同學。