0

我是串行编程的菜鸟,我正在尝试构建一个 com 端口嗅探器,以使用 pthreads 来嗅探两个端口之间的字节。我正在为 com 端口使用 com0com 模拟器。仿真器创建成对连接的 COM 端口。起初,我想用这个场景来嗅探:

应用程序1<--->COM3<--->嗅探器<--->COM4<--->应用程序2

但是,即使在运行应用程序之前将代码中的端口设置为非独占模式,我也无法读取两个端口之间发生的情况,而且应用程序无法访问端口(错误是“访问被拒绝”)。

我尝试过这种情况:Application1<--->COM3<--->COM4<--->Sniffer<--->COM5<--->COM4<--->Application2

有了这个,代码能够读取 COM4 和 COM5,而应用程序读取 COM3 和 COM4。在这种情况下,我能够看到字节并用一个线程向一个方向写入。但是当我尝试使用两个线程来确保双向通信时,它在第一次读取时失败了。

第二种情况的代码:

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <pthread.h>

void setupPort(HANDLE * handle, char * portName);
void * readFromPort(void * handles);
void writeToPort(HANDLE * handle, char data[]);

typedef struct
{
    HANDLE from;
    HANDLE to;
} bi_ports;

int main()
{
    HANDLE first_port, second_port;
    char * first_port_name = "COM4";
    char * second_port_name = "COM5";
    bi_ports *ports_first, *ports_second;
    pthread_t firstToSecondThread, secondToFirstThread;

    setupPort(&first_port, first_port_name);
    setupPort(&second_port, second_port_name);

    ports_first = (bi_ports *) malloc(sizeof(bi_ports));
    ports_second = (bi_ports *) malloc(sizeof(bi_ports));

    ports_first->from = first_port;
    ports_first->to = second_port;

    ports_second->from = second_port;
    ports_second->to = first_port;

    pthread_create(&firstToSecondThread, NULL, readFromPort, (void *) ports_first);
    pthread_create(&secondToFirstThread, NULL, readFromPort, (void *) ports_second);

    pthread_join(firstToSecondThread, NULL);
    pthread_join(secondToFirstThread,NULL);

    return 0;
}

void setupPort(HANDLE * handle, char * portName)
{
    BOOL status;
    *handle = CreateFile(portName,            //port name
                         GENERIC_READ | GENERIC_WRITE, //Read/Write
                         0,            // No Sharing
                         NULL,         // No Security
                         OPEN_EXISTING,// Open existing port only
                         0,            // Non Overlapped I/O
                         NULL);        // Null for Comm Devices


    if (handle == INVALID_HANDLE_VALUE)
    {
        printf("\n%s could not be opened\n", portName);
    }
    else
    {
        printf("\n%s successfully opened.\n", portName);
    }

    DCB dcbSerialParams = { 0 };                         // Initializing DCB structure
    dcbSerialParams.DCBlength = sizeof(dcbSerialParams);

    status = GetCommState(*handle, &dcbSerialParams);      //retreives  the current settings

    if (status == FALSE)
        printf("\n    Error! in GetCommState()");

    dcbSerialParams.BaudRate = CBR_9600;      // Setting BaudRate = 9600
    dcbSerialParams.ByteSize = 8;             // Setting ByteSize = 8
    dcbSerialParams.StopBits = ONESTOPBIT;    // Setting StopBits = 1
    dcbSerialParams.Parity = NOPARITY;        // Setting Parity = None

    status = SetCommState(*handle, &dcbSerialParams);  //Configuring the port according to settings in DCB

    if (status == FALSE)
    {
        printf("\n    Error! in Setting DCB Structure");
    }
    else //If Successful display the contents of the DCB Structure
    {
        printf("\n\n    Setting DCB Structure Successful\n");
        printf("\n       Baudrate = %d", dcbSerialParams.BaudRate);
        printf("\n       ByteSize = %d", dcbSerialParams.ByteSize);
        printf("\n       StopBits = %d", dcbSerialParams.StopBits);
        printf("\n       Parity   = %d", dcbSerialParams.Parity);
    }

    /*------------------------------------ Setting Timeouts --------------------------------------------------*/

    COMMTIMEOUTS timeouts = { 0 };
    timeouts.ReadIntervalTimeout         = 50;
    timeouts.ReadTotalTimeoutConstant    = 50;
    timeouts.ReadTotalTimeoutMultiplier  = 10;
    timeouts.WriteTotalTimeoutConstant   = 50;
    timeouts.WriteTotalTimeoutMultiplier = 10;

    if (SetCommTimeouts(*handle, &timeouts) == FALSE)
        printf("\n\n    Error! in Setting Time Outs");
    else
        printf("\n\n    Setting Serial Port Timeouts Successful");

    /*------------------------------------ Setting Receive Mask ----------------------------------------------*/

    status = SetCommMask(*handle, EV_RXCHAR); //Configure Windows to Monitor the serial device for Character Reception

    if (status == FALSE)
        printf("\n\n    Error! in Setting CommMask");
    else
        printf("\n\n    Setting CommMask successful");
}

void * readFromPort(void * handles)
{
    bi_ports* ports;
    ports = (bi_ports*) handles;

    HANDLE handleFrom;
    HANDLE handleTo;

    handleFrom = ports->from;
    handleTo = ports->to;

    BOOL status;
    DWORD dwEventMask;                     // Event mask to trigger
    char  TempChar;                        // Temporary Character
    char  SerialBuffer[256];               // Buffer Containing Rxed Data
    DWORD NoBytesRead;                     // Bytes read by ReadFile()
    int i = 0;
    DWORD  dNoOFBytestoWrite;
    DWORD  dNoOfBytesWritten = 0;          // No of bytes written to the port

    /*------------------------------------ Setting WaitComm() Event   ----------------------------------------*/

    while(TRUE)
    {
        printf("\n\n    Waiting for Data Reception");

        status = TRUE;//WaitCommEvent(handleFrom, &dwEventMask, NULL); //Wait for the character to be received

        /*-------------------------- Program will Wait here till a Character is received ------------------------*/

        if (status == FALSE)
        {
            printf("\n    Error! in Setting WaitCommEvent()");
        }
        else //If  WaitCommEvent()==True Read the RXed data using ReadFile();
        {
            printf("\n\n    Characters Received\n");
            do
            {
                status = ReadFile(handleFrom, &TempChar, sizeof(TempChar), &NoBytesRead, NULL);
                SerialBuffer[i] = TempChar;
                i++;
            }
            while (NoBytesRead > 0);

            /*------------Printing the RXed String to Console----------------------*/
            if(NoBytesRead > 0){
                printf("\n\n    ");
            int j =0;
            for (j = 0; j < i-1; j++)       // j < i-1 to remove the dupliated last character
            {
                printf("%02X", (unsigned int)(unsigned char)SerialBuffer[j]);
            }

            dNoOFBytestoWrite = sizeof(SerialBuffer);

            status = WriteFile(handleTo,               // Handle to the Serialport
                               SerialBuffer,            // Data to be written to the port
                               dNoOFBytestoWrite,   // No of bytes to write into the port
                               &dNoOfBytesWritten,  // No of bytes written to the port
                               NULL);

            if (status == TRUE)
            {
                printf("\n\n    %X - Written to port", (unsigned int)(unsigned char)SerialBuffer);
            }
            else
            {
                printf("\n\n   Error %d in Writing to Serial Port",GetLastError());
            }
            //CloseHandle(handleTo);

            i=0;
            }

        }

        //CloseHandle(handleFrom);//Closing the Serial Port
        printf("\n +==========================================+\n");
    }

}
4

0 回答 0