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;
}主要用于自己记录,当然也希望能帮组有需要的同学。
本文出自 “chosen” 博客,请务必保留此出处http://xuxueliang.blog.51cto.com/5576502/1357986
原文:http://xuxueliang.blog.51cto.com/5576502/1357986