Header
#pragma once
#include <windows.h>
#include <iostream>
#include <stdlib.h>
#include <WinBase.h>
using namespace std;
class SerialPort {
public:
BOOL COM_exists(int port);
};
cpp
#include "stdafx.h"
#include <string.h>
#include "SerialPort.h"
using namespace std;
BOOL SerialPort::COM_exists(int port)
{
char buffer[7];
COMMCONFIG CommConfig;
DWORD size;
if (!(1 <= port && port <= 255))
{
return FALSE;
}
snprintf(buffer, sizeof buffer, "COM%d", port);
size = sizeof CommConfig;
// COM port exists if GetDefaultCommConfig returns TRUE
// or changes <size> to indicate COMMCONFIG buffer too small.
return (GetDefaultCommConfig(L"buffer", &CommConfig, &size)
|| size > sizeof CommConfig);
}
main
#include "stdafx.h"
#include <iostream>
#include "SerialPort.h"
using namespace std;
if(num==1)
{
int i;
for (i = 1; i < 256; ++i)
{
if (COM_exists(i))
{
cout <<"COM%d \n";
}
}
}
I want listing serial ports on Windows ,but I'm having a hard time.
Help me list the serial ports. error code = c3861 ,e0020
I want listing serial ports on windows.
The end of the road ,Select a serial port that can be connected to enable communication.
please help me
Main problem is here
if(num==1)
{
int i;
for (i = 1; i < 256; ++i)
{
if (COM_exists(i))
{
cout <<"COM%d \n";
}
}
}
In C++ code has to go in functions (a simplification but good enough for now) and the program starts with a special function called main. Also cout <<"COM%d \n"; is not the correct way to print a COM port, I've used the correct way in the code below. Also in the code above what is num supposed to be?
Anyway rewrite as follows and you're a little closer
int main() // start of program
{
int i;
for (i = 1; i < 256; ++i)
{
if (COM_exists(i))
{
cout << "COM " << i << "\n";
}
}
}
There are other problems such as the pointless SerialPort class. I would just remove that.
Replace
class SerialPort {
public:
BOOL COM_exists(int port);
};
with
BOOL COM_exists(int port);
and
BOOL SerialPort::COM_exists(int port)
with
BOOL COM_exists(int port)
The code looks like you are trying to learn C++ by cutting and pasting code from the internet. That is never going to work, C++ is a complex language and really needs formal study to be learned effectively. Here's a curated list of C++ books.
Related
I am currently trying to make a video games using a controller made of an arduino. I am making the GUI with Qt since I found it really cool that it has an integrated serial port library. So right now i'm trying to set-up the communication of the arduino and the pc with QSerial port, so far I'm able to open the port (not a big deal but it took me hours lol), when I try to write in it it get this error :
<3,2,2,>QObject::startTimer: Timers can only be used with threads started with QThread
Here's the com.h file
#include <QSerialPort>
#include <iostream>
using namespace std;
class Comunication
{
public:
void openSerial();
Comunication();
void closeSerial();
bool sendData(int module, int* tabData, uint8_t tabSize);
private:
QSerialPort* serial;
};
And here's the com.cpp file
#include "com.h"
Comunication::Comunication() {
serial = new QSerialPort;
}
void Comunication::openSerial() {
serial->setPortName("COM5");
serial->setBaudRate(QSerialPort::Baud9600, QSerialPort::AllDirections);
serial->setDataBits(QSerialPort::Data8);
serial->setParity(QSerialPort::NoParity);
serial->setFlowControl(QSerialPort::NoFlowControl);
serial->setReadBufferSize(5000);
serial->open(QIODevice::ReadWrite);
if (serial->isOpen()) {
cout << "opened" << endl;
}
}
void Comunication::closeSerial() {
serial->close();
}
bool Comunication::sendData(int module, int* tabData, uint8_t tabSize)
{
char txData[30];
int index = 0;
txData[index++] = '<';
txData[index++] = module + '0';
for (int i = 0; i < tabSize; i++)
{
txData[index++] = ',';
if (tabData[i] != 'I') {
char tempTab[15];
int sizeTempTab = sprintf(tempTab, "%d", tabData[i]);
for (int j = 0; j < sizeTempTab; j++)
{
txData[index++] = tempTab[j];
}
}
else
txData[index++] = 'I';
}
txData[index++] = ',';
txData[index++] = '>';
txData[index] = '\0';
cout << txData;
if (serial->isOpen()) {
serial->write(txData, index);
}
return 0;
}
I'm sure that the port is open... I dont understand what's wrong, is it because it is running in the main thread ?, If so, how do I correct the situation...
If anyone could help it would be much appreciated.
Have a great day/evening
PS: im using 6.2.3
Im trying to make multithreaded proxy checker in c++, when I start the threads and lock it all threads wait till the request is finished. I tried to remove the locks but that doesn't help either. Im using the cpr library to make the requests, the documentation can be found here: https://whoshuu.github.io/cpr/advanced-usage.html.
Reproduceable example:
#include <stdio.h>
#include <pthread.h>
#include <iostream>
#include <queue>
#include <mutex>
#include <cpr/cpr.h>
#include <fmt/format.h>
#define NUMT 10
using namespace std;
using namespace fmt;
std::mutex mut;
std::queue<std::string> q;
void* Checker(void* arg) {
while (!q.empty()) {
mut.lock();
//get a webhook at https://webhook.site
string protocol = "socks4";
string proxyformatted = format("{0}://{1}", protocol, q.front());
auto r = cpr::Get(cpr::Url{ "<webhook url>" },
cpr::Proxies{ {"http", proxyformatted}, {"https", proxyformatted} });
q.pop();
mut.unlock();
}
return NULL;
}
int main(int argc, char** argv) {
q.push("138.201.134.206:5678");
q.push("185.113.7.87:5678");
q.push("5.9.16.126:5678");
q.push("88.146.196.181:4153");
pthread_t tid[NUMT]; int i;
int thread_args[NUMT];
for (i = 0; i < NUMT; i++) {
thread_args[i] = i;
pthread_create(&tid[i], NULL, Checker, (void*) &thread_args);
}
for (i = 0; i < NUMT; i++) {
pthread_join(tid[i], NULL);
fprintf(stderr, "Thread %d terminated\n", i);
}
return 0;
}
Thanks in advance.
I suggest to implement a wrapper class for your queue that will hide the mutex.
That class can provide push(std::string s) and bool pop(std::string& s) that returns true and populate s if the queue wasn't empty or false othervise. Then your worker threads can simply loop
std::string s;
while(q.pop(s)) {
...
}
I am trying to create a tunnel and car threads that simulate a tunnel that only goes one way. Lets say each way is W and B. The way to W is open for 5 seconds, then the tunnel is closed for another 5, then the tunnel is open for way B for 5 seconds and then closed for another 5, then repeat.
I have created the tunnel thread with the tunnelf function but it does not do anything but print the first line: "The tunnel is now open to Whittier Bound traffic". And it only does that sometimes. Each time i compile the code, it can either print nothing or that line. It does not go through the required outputs. Meanwhile if i put the exact same while loop from the tunnelf thread into main, it works
#include <iostream>
#include <cstring>
#include <string>
#include <cctype>
#include <iomanip>
#include <fstream>
#include <sstream>
#include <pthread.h>
#include <conio.h>
#include <windows.h>
#include <ctime>
#include <cerrno>
#include <unistd.h>
using namespace std;
void *car(void *arg);
void *tunnelf();
static pthread_mutex_t traffic_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t car_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t bbcan = PTHREAD_COND_INITIALIZER;
static pthread_cond_t wbcan =PTHREAD_COND_INITIALIZER;
static pthread_cond_t not_full = PTHREAD_COND_INITIALIZER;
static bool whittierBound = false;
static bool bbBound = false;
struct car2{
int arrive;
int cross;
string bound;
};
int main(){
ifstream in;
in.open("Thrd.txt");
if (in.fail()){
cout<< "failed to open file";
exit(1);
}
car2 record[50];
int max_cars;
int arrive;
int cross;
string bound;
string data;
int i = 0;
in >> max_cars;
cout<<"Num cars "<<max_cars<<endl;
while(!in.eof()){
in >> record[i].arrive >>record[i].bound >> record[i].cross;
i++;
}
int size = i;
for(int i= 0; i<size; i++){
cout << record[i].arrive <<record[i].bound <<record[i].cross<<endl;
}
pthread_t cartid[max_cars];
pthread_t tunnel;//just shared variable for the tunnel
pthread_create(&tunnel, NULL, &tunnelf, NULL);
in.close();
}
void *tunnelf(){
static int done;
while(done==0){
pthread_mutex_lock(&traffic_lock);
whittierBound = true;
cout << "The tunnel is now open to Whiitier-bound traffic"<<endl;
pthread_cond_broadcast(&wbcan);
pthread_mutex_unlock(&traffic_lock);
sleep(5);
pthread_mutex_lock(&traffic_lock);
whittierBound = false;
cout << "The tunnel is now closed to all traffic"<<endl;
pthread_mutex_unlock(&traffic_lock);
sleep(5);
pthread_mutex_lock(&traffic_lock);
bbBound = true;
cout << "The tunnel is now open to Bear-Valley-bound traffic"<<endl;
pthread_cond_broadcast(&bbcan);
pthread_mutex_unlock(&traffic_lock);
sleep(5);
pthread_mutex_lock(&traffic_lock);
bbBound = false;
cout << "The tunnel is now closed to all traffic"<<endl;
pthread_mutex_unlock(&traffic_lock);
}
}
One thing to mention, you never guard against array overruns. In C++17, you can use std::size. You might consider using std::array for record, which would help in debug builds (but not release)
while(!in.eof() && i<std::size(record)){
in >> record[i].arrive >>record[i].bound >> record[i].cross;
// cout <<arrive<<" " << bound<<" " << cross<<endl;
i++;
}
I am trying to use the Boost 1.60.0 library with Intel Pin 2.14-71313-msvc12-windows. The following piece of code is the simple implementation I did to try things out:
#define _CRT_SECURE_NO_WARNINGS
#include "pin.H"
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <stdlib.h>
#include <sstream>
#include <time.h>
#include <boost/lockfree/spsc_queue.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
namespace boost_network{
#include <boost/asio.hpp>
#include <boost/array.hpp>
}
//Buffersize of lockfree queue to use
const int BUFFERSIZE = 1000;
//Tracefiles for error / debug purpose
std::ofstream TraceFile;
//String wrapper for boost queue
class statement {
public:
statement(){ s = ""; }
statement(const std::string &n) : s(n) {}
std::string s;
};
//string queue to store inserts
boost::lockfree::spsc_queue<statement, boost::lockfree::capacity<BUFFERSIZE>> buffer; // need lockfree queue for multithreading
//Pin Lock to synchronize buffer pushes between threads
PIN_LOCK lock;
KNOB<string> KnobOutputFile(KNOB_MODE_WRITEONCE, "pintool", "o", "calltrace.txt", "specify trace file name");
KNOB<BOOL> KnobPrintArgs(KNOB_MODE_WRITEONCE, "pintool", "a", "0", "print call arguments ");
INT32 Usage()
{
cerr << "This tool produces a call trace." << endl << endl;
cerr << KNOB_BASE::StringKnobSummary() << endl;
return -1;
}
VOID ImageLoad(IMG img, VOID *)
{
//save module informations
buffer.push(statement("" + IMG_Name(img) + "'; '" + IMG_Name(img).c_str() + "'; " + IMG_LowAddress(img) + ";"));
}
VOID Fini(INT32 code, VOID *v)
{
}
void do_somenetwork(std::string host, int port, std::string message)
{
boost_network::boost::asio::io_service ios;
boost_network::boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::address::from_string(host), port);
boost_network::boost::asio::ip::tcp::socket socket(ios);
socket.connect(endpoint);
boost_network::boost::system::error_code error;
socket.write_some(boost_network::boost::asio::buffer(message.data(), message.size()), error);
socket.close();
}
void WriteData(void * arg)
{
int popped; //actual amount of popped objects
const int pop_amount = 10000;
statement curr[pop_amount];
string statement = "";
while (1) {
//pop more objects from buffer
while (popped = buffer.pop(curr, pop_amount))
{
//got new statements in buffer to insert into db: clean up statement
statement.clear();
//concat into one statement
for (int i = 0; i < popped; i++){
statement += curr[i].s;
}
do_somenetwork(std::string("127.0.0.1"), 50000, sql_statement.c_str());
}
PIN_Sleep(1);
}
}
int main(int argc, char *argv[])
{
PIN_InitSymbols();
//write address of label to TraceFile
TraceFile.open(KnobOutputFile.Value().c_str());
TraceFile << &label << endl;
TraceFile.close();
// Initialize the lock
PIN_InitLock(&lock);
// Initialize pin
if (PIN_Init(argc, argv)) return Usage();
// Register ImageLoad to be called when an image is loaded
IMG_AddInstrumentFunction(ImageLoad, 0);
//Start writer thread
PIN_SpawnInternalThread(WriteData, 0, 0, 0);
PIN_AddFiniFunction(Fini, 0);
// Never returns
PIN_StartProgram();
return 0;
}
When I build the above code, Visual Studio cannot find boost_network::boost::asio::ip and keeps giving error saying asio::ip does not exist. I had previously posted this question myself:
Sending data from a boost asio client
and after using the provided solution in the same workspace, the code worked fine and I was able to communicate over the network. I am not sure what is going wrong here. For some reason using the different namespace seems to not work out because it says boost must be in the default namespace.
However, if I do not add the namespace, in that case the line,
KNOB<BOOL> KnobPrintArgs(KNOB_MODE_WRITEONCE, "pintool", "a", "0", "print call arguments ");
throws an error saying BOOL is ambiguous.
Kindly suggest what should be a viable solution in this situation. I am using Visual Studio 2013.
The same piece of code with only Pin also works with out the network part and I can write data generated from Pin into a flat file.
I am relatively new to C++, so please forgive my lack of knowledge. I need help regarding TFTP packets. Below is the code I am using to generate a WRQ (write request package) and DATA packet which will be sent to a designated server.
bool createWRQ(char * filename) {
/* structure is the same as RRQ */
clear();
addWord(TFTP_OPCODE_WRITE);
addString(filename);
addByte(0);
addString(TFTP_DEFAULT_TRANSFER_MODE);
addByte(0);
return true;
}
bool createData(int block, char * mData, int data_size) {
/* 2 bytes 2 bytes n bytes
----------------------------------------
DATA | 03 | Block # | Data |
---------------------------------------- */
clear(); // to clean the memory location
addWord(TFTP_OPCODE_DATA);
addWord(block);
addMemory(mData, data_size);
return true;
}
I will include the declarations and required functions.
#include "stdafx.h"
#include "WebComm.h"
#include "WebCommDlg.h"
#include <stdio.h>
#include <stdlib.h>
#include "visa.h"
#include <cstring>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <winsock.h>
#include <string.h>
#include <string>
#include <fstream>
#include <cstdio>
#include <cerrno>
int mCurPacketSize = 512;
char mData[512];
#define VIBUF_LEN 255
#define TFTP_OPCODE_READ 1
#define TFTP_OPCODE_WRITE 2
#define TFTP_OPCODE_DATA 3
#define TFTP_OPCODE_ACK 4
#define TFTP_OPCODE_ERROR 5
#define cTFTPPacket_MAX_SIZE 1024
#define cTFTPPacket_DATA_SIZE 512
#define TFTP_DEFAULT_TRANSFER_MODE "octet" //"netascii", "octet", or "mail"
typedef unsigned char BYTE;
typedef unsigned short WORD;
bool addByte(BYTE b) {
if(mCurPacketSize >= cTFTPPacket_MAX_SIZE)
return false;
mData[mCurPacketSize] = (unsigned char)b;
mCurPacketSize++;
return true;
}
bool addWord(WORD w) {
w = htons(w);
if(!addByte(*(((BYTE*)&w)+1)))
return false;
return !addByte(*((BYTE*)&w));
}
bool addString(char * str) {
int n = strlen(str);
for(int i=0; i<n; i++)
if(!addByte(str[i]))
return false;
return true;
}
bool addMemory(char * buffer, int len) {
bool oStatus = false;
if(mCurPacketSize + len >= cTFTPPacket_MAX_SIZE) {
AfxMessageBox("Packet max size exceeded");
return false;
} else {
memcpy(mData + mCurPacketSize), buffer, len);
mCurPacketSize += len;
return true;
}
}
void clear() {
mCurPacketSize = 0;
memset(mData, mCurPacketSize, cTFTPPacket_MAX_SIZE);
}
I am aware these function have been declared mostly as type bool, however I need to send a WRQ packet to the server and wait for an ACK response before sending a DATA packet.
Something along the lines of:
while(/* something */)
if(!sendto(socket, WRQ, 512, NULL, (sockaddr*)&Addr, sizeof(struct sockaddr_in)))){
if(!recvfrom(socket, ACK, /* ... */))
sendto(socket, DATA_Packet, 512, NULL, (sockaddr*)&Addr, sizeof(struct sockaddr_in))));
My question is: how can I modify the createWRQ() and createData() functions so that I can return them as packets to use for transmission, since bool only returns true or false as 1 or 0.
I need to be able to send them using the winsock send and receive functions. Apologies for the silly question. If anyone could point me in the right direction I would greatly appreciate it.
your whole approach has a few issues...
When you create your packets relying on functions like
bool addByte(BYTE b)
they use global variables
mCurPacketSize, mData
that's not good. You could use instead something on these lines
int addByte(char* Pkt, int PktIdx, BYTE b)
{
if (PktIdx > cTFTPPacket_MAX_SIZE)
{
return 0;
}
Pkt[PktIdx] = (unsigned char)b;
PktIdx++;
return PktIdx;
}
then you know that Pkt is always the head of your packet and PktIdx is either the place for a new byte (or string) and "also" the size of the packet.
When you create packets that have a fixed length structure (or a fixed length header followed by a variable length payload area) it is a good idea to represent the fixed length area with a "packed" (pay attention to memory alignment) C/C++ structure and then populate the structure.