I'm making an application that moves that mouse via the joystick module. I'm using C++ because my board doesn't support Mouse.move from the Arduino IDE.
I've run into an issue where if I push the joystick all the way back to where the X value is 1024 the command console that's printing the values out stops printing at all, no empty strings just paused. But if I look at the Serial monitor from the Arduino IDE I see it's continuously printing 1024, 513 printed as it should.
I find that when I do this with the Y value it prints 1024 to both Arduino IDE and C++ Serial Monitors just fine. e.g 513, 1024
I'm fairly new to using C++ with the Arduino, it might be something simple.
JoystickModule.ino (Arduino code)
#define BAUD 9600
const int SW_pin = 2;
const int X_pin = 0;
const int Y_pin = 1;
void setup(){
Serial.begin(BAUD);
pinMode(SW_pin, INPUT);
digitalWrite(SW_pin, HIGH);
}
void loop(){
Serial.println((String)analogRead(X_pin) + "," + (String)analogRead(Y_pin));
delay(100);
}
main.cpp
#include "stdafx.h"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <sstream>
#include <string>
#include <Windows.h>
#include "SerialPort.h"
#include <vector>
using namespace std;
//portname must contain these backslashes, and remember to replace the following com port
char *port_name = "\\\\.\\COM4";
//String for incoming data
char incomingData[MAX_DATA_LENGTH];
int main() {
SerialPort arduino(port_name);
if (arduino.isConnected()) cout << "Connection Established" << endl;
else cout << "ERROR, check port name";
while (arduino.isConnected()) {
int read_result = arduino.readSerialPort(incomingData, MAX_DATA_LENGTH);
//store into array for later use by splitting by "," e.g. "513, 508"
//result[0] will store the X val and result[1] will store the Y val
string result[2];
int xVal = 0;
int yVal = 0;
string data = (string)incomingData;
size_t pos = data.find(",");
result[0] = data.substr(0, pos);
result[1] = data.substr(pos + 1, 4);
cout << data << endl;
Sleep(100);
}
return 0;
}
Header Files and other resources from this tutorial
SerialPort.h
#pragma once
#ifndef SERIALPORT_H
#define SERIALPORT_H
#define ARDUINO_WAIT_TIME 2000
#define MAX_DATA_LENGTH 255
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
class SerialPort
{
private:
HANDLE handler;
bool connected;
COMSTAT status;
DWORD errors;
public:
SerialPort(char *portName);
~SerialPort();
int readSerialPort(char *buffer, unsigned int buf_size);
bool writeSerialPort(char *buffer, unsigned int buf_size);
bool isConnected();
};
#endif // SERIALPORT_H
SerialPort.cpp
#include "stdafx.h"
#include "SerialPort.h"
SerialPort::SerialPort(char *portName)
{
this->connected = false;
this->handler = CreateFileA(static_cast<LPCSTR>(portName),
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (this->handler == INVALID_HANDLE_VALUE) {
if (GetLastError() == ERROR_FILE_NOT_FOUND) {
printf("ERROR: Handle was not attached. Reason: %s not available\n", portName);
}
else
{
printf("ERROR!!!");
}
}
else {
DCB dcbSerialParameters = { 0 };
if (!GetCommState(this->handler, &dcbSerialParameters)) {
printf("failed to get current serial parameters");
}
else {
dcbSerialParameters.BaudRate = CBR_9600;
dcbSerialParameters.ByteSize = 8;
dcbSerialParameters.StopBits = ONESTOPBIT;
dcbSerialParameters.Parity = NOPARITY;
dcbSerialParameters.fDtrControl = DTR_CONTROL_ENABLE;
if (!SetCommState(handler, &dcbSerialParameters))
{
printf("ALERT: could not set Serial port parameters\n");
}
else {
this->connected = true;
PurgeComm(this->handler, PURGE_RXCLEAR | PURGE_TXCLEAR);
Sleep(ARDUINO_WAIT_TIME);
}
}
}
}
SerialPort::~SerialPort()
{
if (this->connected) {
this->connected = false;
CloseHandle(this->handler);
}
}
int SerialPort::readSerialPort(char *buffer, unsigned int buf_size)
{
DWORD bytesRead;
unsigned int toRead;
ClearCommError(this->handler, &this->errors, &this->status);
if (this->status.cbInQue > 0) {
if (this->status.cbInQue > buf_size) {
toRead = buf_size;
}
else toRead = this->status.cbInQue;
}
if (ReadFile(this->handler, buffer, toRead, &bytesRead, NULL)) return bytesRead;
return 0;
}
bool SerialPort::writeSerialPort(char *buffer, unsigned int buf_size)
{
DWORD bytesSend;
if (!WriteFile(this->handler, (void*)buffer, buf_size, &bytesSend, 0)) {
ClearCommError(this->handler, &this->errors, &this->status);
return false;
}
else return true;
}
bool SerialPort::isConnected()
{
return this->connected;
}
Thank you in advance.
Related
I'm going to do serial communication using visual studio c++.
However, when I try to use 'serialport port open', I get an error with the phrase L"//./com3
The error code is c2665, e0289.
Also, there is a possibility that the open port may change from time to time, so please help me to read the port automatically.
serialport.h
#pragma once
#include <windows.h>
#include <iostream>
#include <stdlib.h>
using namespace std;
class SerialPort {
public:
HANDLE hComm;
LPCWSTR COMport;
DWORD dNoOFBytestoWrite;
DWORD dNoOfBytesWritten;
int BufSize;
int Status;
char* SerialBuffer;
char* commandBuffer;
DWORD NoBytesRead;
SerialPort(LPCWSTR COMport, int setBaudRate, int setByteSize, char* commandBuffer, int BufSize);
void Connect(LPCWSTR COMport, int setBaudRate, int setByteSize, char* commandBuffer);
void sendCommand(int setBaudRate, int setByteSize, char* commandBuffer);
void getData();
};
serial.cpp
#include "stdafx.h"
#include <string.h>
#include "SerialPort.h"
SerialPort::SerialPort(LPCWSTR COM, int setBaudRate, int setByteSize, char* commandBuffer, int BufSize) {
this->BufSize = BufSize;
this->SerialBuffer = new char[BufSize];
this->NoBytesRead = BufSize;
Connect(COM, setBaudRate, setByteSize, commandBuffer);
}
void SerialPort::Connect(LPCWSTR COM, int setBaudRate, int setByteSize, char* commandBuffer) {
this->COMport = COM;
this->hComm = CreateFile(COM, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); // (port name, read/write , no sharing , no security, open existing port only, non overlapped i/o , null for comm devices)
if (this->hComm == INVALID_HANDLE_VALUE)
cout << "Error in Opening serial port" << endl;
else {
cout << "Opening serial port successful" << endl;
sendCommand(setBaudRate, setByteSize, commandBuffer);
}
}
void SerialPort::sendCommand(int setBaudRate, int setByteSize, char* commandBuffer) {
this->commandBuffer = commandBuffer;
this->dNoOFBytestoWrite = sizeof(commandBuffer);
this->Status = WriteFile(hComm, commandBuffer, dNoOFBytestoWrite, &dNoOfBytesWritten, NULL);
DCB dcbSerialParams = { 0 };
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
dcbSerialParams.BaudRate = setBaudRate;
dcbSerialParams.ByteSize = setByteSize;
dcbSerialParams.StopBits = ONESTOPBIT;
dcbSerialParams.Parity = NOPARITY;
COMMTIMEOUTS timeouts = { 0 };
timeouts.ReadIntervalTimeout = 10;
timeouts.ReadTotalTimeoutConstant = 10;
timeouts.ReadTotalTimeoutMultiplier = 10;
timeouts.WriteTotalTimeoutConstant = 50;
timeouts.WriteTotalTimeoutMultiplier = 10;
if (this->Status)
cout << "Command Successful" << endl;
else
{
cout << "fail to Command" << endl;
}
}
void SerialPort::getData() {
ReadFile(this->hComm, &*this->SerialBuffer, this->BufSize, &this->NoBytesRead, NULL);
}
main.cpp
#include "stdafx.h"
#include "SerialPort.h"
int main()
{
SerialPort PortOpen( L"//./com3", CBR_115200, 8, "#or", 24);
PortOpen.getData();
PortOpen.getData();
cout << PortOpen.SerialBuffer << endl;
return 0;
}
I have a device connected via USB, which is outputting a stream of characters separated by a newline, every few seconds. I want to repeatedly poll this device for input without blocking on the event that no such input exists.
I am trying to use the poll() function as recommended on other questions, however, it is not working, and I am having trouble determining where I am going wrong.
My device is at /dev/TTYACM0 and when I run cat /dev/TTYACM) I can see the stream of data.
This is my current program, however it just causes a segmentation fault:
#include <iostream>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <poll.h>
#include <unistd.h>
int main (int argc, char* argv[]){
char buf[1024];
int fd = open("/dev/ttyACM0", O_RDONLY | O_NONBLOCK);
int ret;
if (fd < 0){
std::cout << "ERROR" << fd << std::endl;
}
int i;
struct pollfd *pfds;
while(1){
pfds->fd = 0;
pfds->events = POLLIN;
ret = poll(pfds, 1, 0);
if (ret > 0) {
if (pfds->revents & POLLWRBAND)
{
i = read(0, buf, 1024);
if (!i){
printf("stdin closed\n");
return 0;
}
std::cout << i << std::endl;
}
}
}
return 0;
}
UPDATE:
I fixed the code, here is the working version
#include <poll.h>
#include <iostream>
#include <cstring>
#include <fcntl.h>
#include <unistd.h>
int main(){
char readBuf[5];
char c;
std::string buf;
int counter = 0;
int ret;
int i;
struct pollfd mypoll;
int fd = open("/dev/ttyACM0", O_RDONLY | O_NONBLOCK);
//init mypoll
memset(&mypoll, 0, sizeof(mypoll));
mypoll.fd = fd;
mypoll.events = POLLIN;
while(1){
// poll (pointer to pollfd, number of polls, timeout)
// noneg = successful poll
// 0 = systemcall timeout (no data)
// -1, errno set to indicate error
ret = poll(&mypoll, 1, 0);
if (ret == 1){
int bytes_read = read(fd, readBuf, sizeof(readBuf));
for (i = 0; readBuf[i] != '\n' && i < bytes_read; i++){
buf.push_back(readBuf[i]);
}
std::cout << "#" << buf << "#" << std::endl;
buf = "";
}
}
printf("done\n");
close(fd);
return 0;
}
I want to connect a seairl port with C++ using USB hub (USB splliter).
I have a code that works perfectly fine with my COM ports, but when I'm trying to use the USB hub, I get an error says the COM port not available (even though I see it in the device manager).
I there a way to connect a USB hub COM port in C++?
I attached my current code if necessary. Thank you!
SerialPort.hpp:
/*
* Author: Manash Kumar Mandal
* Modified Library introduced in Arduino Playground which does not work
* This works perfectly
* LICENSE: MIT
*/
#pragma once
#define ARDUINO_WAIT_TIME 2000
#define MAX_DATA_LENGTH 1024
#include <windows.h>
#include <iostream>
#include <string>
class SerialPort {
private:
std::string readBuffer;
HANDLE handler;
bool connected;
COMSTAT status;
DWORD errors;
public:
explicit SerialPort(const char* portName, DWORD baudRate = CBR_9600);
~SerialPort();
int readSerialPort(const char* buffer, unsigned int buf_size);
int readSerialPortUntil(std::string* payload, std::string until);
bool writeSerialPort(const char* buffer, unsigned int buf_size);
bool writeSerialPort(std::string payload);
bool isConnected();
void closeSerial();
};
SerialPort.cpp:
/*
* Author: Manash Kumar Mandal
* Modified Library introduced in Arduino Playground which does not work
* This works perfectly
* LICENSE: MIT
*/
#include <windows.h>
#include <iostream>
#include <string>
#include "SerialPort.hpp"
SerialPort::SerialPort(const char* portName, DWORD baudRate) {
this->connected = false;
this->handler = CreateFileA(static_cast<LPCSTR>(portName),
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (this->handler == INVALID_HANDLE_VALUE) {
if (GetLastError() == ERROR_FILE_NOT_FOUND) {
std::cerr << "ERROR: Handle was not attached.Reason : " << portName << " not available\n";
} else {
std::cerr << "ERROR!!!\n";
}
} else {
DCB dcbSerialParameters = { 0 };
if (!GetCommState(this->handler, &dcbSerialParameters)) {
std::cerr << "ERROR: Failed to get current serial parameters\n";
} else {
dcbSerialParameters.BaudRate = baudRate;
dcbSerialParameters.ByteSize = 8;
dcbSerialParameters.StopBits = ONESTOPBIT;
dcbSerialParameters.Parity = NOPARITY;
dcbSerialParameters.fDtrControl = DTR_CONTROL_ENABLE;
if (!SetCommState(handler, &dcbSerialParameters)) {
std::cout << "ALERT: could not set serial port parameters\n";
} else {
this->connected = true;
PurgeComm(this->handler, PURGE_RXCLEAR | PURGE_TXCLEAR);
Sleep(ARDUINO_WAIT_TIME);
}
}
}
}
SerialPort::~SerialPort() {
if (this->connected) {
this->connected = false;
CloseHandle(this->handler);
}
}
// Reading bytes from serial port to buffer;
// returns read bytes count, or if error occurs, returns 0
int SerialPort::readSerialPort(const char* buffer, unsigned int buf_size) {
DWORD bytesRead{};
unsigned int toRead = 0;
ClearCommError(this->handler, &this->errors, &this->status);
if (this->status.cbInQue > 0) {
if (this->status.cbInQue > buf_size) {
toRead = buf_size;
} else {
toRead = this->status.cbInQue;
}
}
memset((void*)buffer, 0, buf_size);
if (ReadFile(this->handler, (void*)buffer, toRead, &bytesRead, NULL)) {
return bytesRead;
}
return 0;
}
int SerialPort::readSerialPortUntil(std::string* payload, std::string until) {
int untilLen = until.length(), len;
do {
char buffer[MAX_DATA_LENGTH];
int bytesRead = this->readSerialPort(buffer, MAX_DATA_LENGTH);
if (bytesRead == 0) {
int endIndex = this->readBuffer.find(until);
if (endIndex != -1) {
int index = endIndex + untilLen;
*payload = this->readBuffer.substr(0, index);
this->readBuffer = this->readBuffer.substr(index);
}
return bytesRead;
}
this->readBuffer += std::string(buffer);
len = this->readBuffer.length();
} while (this->readBuffer.find(until) == std::string::npos);
int index = this->readBuffer.find(until) + untilLen;
*payload = this->readBuffer.substr(0, index);
this->readBuffer = this->readBuffer.substr(index);
return index;
}
// Sending provided buffer to serial port;
// returns true if succeed, false if not
bool SerialPort::writeSerialPort(const char* buffer, unsigned int buf_size) {
DWORD bytesSend;
if (!WriteFile(this->handler, (void*)buffer, buf_size, &bytesSend, 0)) {
ClearCommError(this->handler, &this->errors, &this->status);
return false;
}
return true;
}
bool SerialPort::writeSerialPort(std::string payload) {
return this->writeSerialPort(payload.c_str(), payload.length());
}
// Checking if serial port is connected
bool SerialPort::isConnected() {
if (!ClearCommError(this->handler, &this->errors, &this->status)) {
this->connected = false;
}
return this->connected;
}
void SerialPort::closeSerial() {
CloseHandle(this->handler);
}
I am working on a project which need to operate two serial port as the same time on windows, but whatever I try I can only open one serial port. Unless repeat open and close, I can operate the two ports but it is too slow. I need to write and read first port and formalize it by protocol and sent it to another port, but I can not initial two port. I was using open and close two ports repeatly to do that before but it was toooooooo slow. Anybody know how to open two port in the same time; Thx!!!
here are my code here:
#include <iostream>
#include <iomanip>
#include "udp.h"
#include "Serial.h"
#include "Formalized.h"
using namespace std;
bool sthread = false;
unsigned char status[6] = {};
HANDLE hMutex = NULL;
DWORD WINAPI ULTRAread(LPVOID lpParamter)
{
Cserial ultra;
unsigned char input0[7] = { 0x00,0x01,0x00,0x01,0x01,0xE5,0xAC };
unsigned char input1[7] = { 0x00,0x02,0x00,0x01,0x01,0xE5,0xE8 };
unsigned char input2[7] = { 0x00,0x03,0x00,0x01,0x01,0xE4,0x14 };
unsigned char input3[7] = { 0x00,0x04,0x00,0x01,0x01,0xE5,0x60 };
unsigned char input4[7] = { 0x00,0x05,0x00,0x01,0x01,0xE4,0x9C };
unsigned char input5[7] = { 0x00,0x06,0x00,0x01,0x01,0xE4,0xD8 };
unsigned char* input[6] = { input0,input1,input2,input3,input4,input5 };
unsigned char pool[8] = {};
if (!ultra.Initcom("COM10")) //ultrasonic COM interface
{
cout << "Init ultrasonic failure \n";
getchar();
sthread = false;
}
else
{
sthread = true;
for (;;)
{
WaitForSingleObject(hMutex, INFINITE);
for (int i = 0; i < 6; i++)
{
if (ultra.Write(input[i], 7))
{
ultra.Read(pool, 8);
}
switch (pool[5])
{
case 0x01:
status[i] = 0x01;
break;
case 0x00:
status[i] = 0x00;
break;
}
}
Sleep(5000);
ReleaseMutex(hMutex);
}
}
}
int main()
{
HANDLE uThread = CreateThread(NULL, 0, ULTRAread, NULL, 0, NULL);
hMutex = CreateMutex(NULL, FALSE, "ultrasonics status");
Cserial zigbee;
cUDP UWB;
char buff[300];
char data[256];
if (!UWB.Initial(6685)) //latitude and longitude port
{
cout << "UWB Port connecting failure \n";
getchar();
}
else
{
cout << "UWB Com connecting success \n";
}
if (!zigbee.Initcom("COM7")) //zigbee access port
{
cout << "Zigbee Initial Failure! \n";
getchar();
}
else
{
cout << "Zigbee Initial Success! \n";
}
for (;;)
{
WaitForSingleObject(hMutex, INFINITE);
switch (sthread)
{
case TRUE: //ultrasonics trustful
WaitForSingleObject(hMutex, INFINITE);
cout << "1";
ReleaseMutex(hMutex);
break;
case FALSE:
cout << "2";
break;
}
Sleep(5000);
}
CloseHandle(uThread);
getchar();
return 0;
}
#include"Serial.h"
Cserial::Cserial()
{
hcom = INVALID_HANDLE_VALUE;
}
Cserial::~Cserial()
{
}
bool Cserial::Initcom(LPCSTR Port)
{
hcom = CreateFile(Port, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL, 0);
if (hcom == INVALID_HANDLE_VALUE)
{
fprintf(stderr, "fail serial1\n");
return false;
}
SetupComm(hcom, 1024, 1024);
DCB dcb;
GetCommState(hcom, &dcb);
dcb.BaudRate = 9600;
dcb.ByteSize = 8;
dcb.Parity = 0;
dcb.StopBits = 1;
SetCommState(hcom, &dcb);
COMMTIMEOUTS CommTimeouts;
GetCommTimeouts(hcom, &CommTimeouts);
CommTimeouts.ReadIntervalTimeout = MAXDWORD;
CommTimeouts.ReadTotalTimeoutMultiplier = 10;
CommTimeouts.ReadTotalTimeoutConstant = 100;
CommTimeouts.WriteTotalTimeoutMultiplier = 1;
CommTimeouts.WriteTotalTimeoutConstant = 10;
if (!SetCommTimeouts(hcom, &CommTimeouts))
{
fprintf(stderr, "fail serial2\n");
return FALSE;
}
return true;
}
void Cserial::Uninitcom()
{
CloseHandle(hcom);
hcom = INVALID_HANDLE_VALUE;
}
bool Cserial::Clearcom()
{
PurgeComm(hcom, PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR | PURGE_TXABORT);
return TRUE;
}
bool Cserial::Write(unsigned char* buf, int len)
{
if (hcom == INVALID_HANDLE_VALUE)
{
return FALSE;
}
DWORD dwWrittenLen = 0;
if (!WriteFile(hcom, buf, len, &dwWrittenLen, NULL))
{
return FALSE;
}
else
{
return TRUE;
}
}
bool Cserial::Read(unsigned char* buf, int len)
{
DWORD dwReadLen = 0;
if (hcom == INVALID_HANDLE_VALUE)
{
return FALSE;
}
if (!ReadFile(hcom, buf, len, &dwReadLen, NULL))
{
return FALSE;
}
else
{
return TRUE;
}
}
I'm doing an implementation of FTP, now I'm implementing the RETR command, I take the errno code 88 when I try to do "get FILENAME".
I think that the error can be the conversion of unsigned to uint32_t and uint16_t in the port command.
#include <cstring>
#include <cstdarg>
#include <cstdio>
#include <cerrno>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>
#include <locale.h>
#include <langinfo.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <iostream>
#include <dirent.h>
#include "common.h"
#include "ClientConnection.h"
ClientConnection::ClientConnection(int s) {
int sock = (int)(s);
char buffer[MAX_BUFF];
control_socket = s;
// Consultar la documentación para conocer el funcionamiento de fdopen.
fd = fdopen(s, "a+");
if (fd == NULL){
std::cout << "Connection closed" << std::endl;
fclose(fd);
close(control_socket);
ok = false;
return ;
}
ok = true;
data_socket = -1;
};
ClientConnection::~ClientConnection() {
fclose(fd);
close(control_socket);
}
int connect_TCP(uint32_t address, uint16_t port) {
struct sockaddr_in sin;
struct hostent
*hent;
int s;
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons(port);
sin.sin_addr.s_addr = address;
//if(hent = gethostbyname(address))
//memcpy(&sin.sin_addr,hent->h_addr,hent->h_length);
//else if ((sin.sin_addr.s_addr = inet_addr((char*)address)) == INADDR_NONE)
//errexit("No puedo resolver el nombre \"%s\"\n", address);
s = socket(AF_INET, SOCK_STREAM, 0);
if(s < 0){
printf("No se puede crear el socket\n");
return 0;
}
if(connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0){
printf("No se puede conectar con %u\n", address);
return 0;
}
return s;
}
void ClientConnection::stop() {
close(data_socket);
close(control_socket);
parar = true;
}
#define COMMAND(cmd) strcmp(command, cmd)==0
void ClientConnection::WaitForRequests() {
if (!ok) {
return;
}
fprintf(fd, "220 Service ready\n");
while(!parar) {
fscanf(fd, "%s", command);
if (COMMAND("USER")) {
fscanf(fd, "%s", arg);
fprintf(fd, "331 User name ok, need password\n");
}
else if (COMMAND("PWD")) {
}
else if (COMMAND("PASS")) {
char pass[30];
fscanf(fd,"%s",pass);
fprintf(fd,"230 User logged in\n");
}
else if (COMMAND("PORT")) {
unsigned ip[4];
unsigned port[2];
fscanf(fd,"%u,%u,%u,%u,%u,%u",&ip[0],&ip[1],&ip[2],&ip[3],&port[0],&port[1]);
uint32_t aux1;
uint16_t aux2;
aux1 = ip[3] << 24 | ip[2] << 16 | ip[1] << 8 | ip[0];
aux2 = port[1]*256 + port[0];
data_socket = connect_TCP(aux1,aux2);
fprintf(fd,"200 OK\n");
}
else if (COMMAND("PASV")) {
}
else if (COMMAND("CWD")) {
}
else if (COMMAND("STOR") ) { //put
FILE* fp = fopen("filename","w+");
int size_buffer = 512;
char buffer[size_buffer];
int recived_datas;
while(recived_datas == size_buffer){
datos_recibidos = recv(data_socket,buffer,size_buffer,0);
fwrite(buffer,1,recived_datas,fp);
}
close(data_socket);
fclose(fp);
}
else if (COMMAND("SYST")) {
fprintf(fd,"SYSTEM DETAILS\n");
}
else if (COMMAND("TYPE")) {
fprintf(fd,"type 1");
}
else if (COMMAND("RETR")) {
fscanf(fd,"%s",arg);
std::cout << "Argument: " << arg << std::endl;
FILE* fp = fopen(arg,"r+");
int sent_datas;
int size_buffer = 512;
char buffer[size_buffer];
std::cout << "Buffer size = " << size_buffer << std::endl;
do{
sent_datas = fread(buffer,size_buffer,1,fp);
printf("Code %d | %s\n",errno,strerror(errno));
send(data_socket,buffer,sent_datas,0);
printf("Code %d | %s\n",errno,strerror(errno));
}while(sent_datas == size_buffer);
close(data_socket);
fclose(fp);
fprintf(fd,"Transferencia completada");
}
else if (COMMAND("QUIT")) {
}
else if (COMMAND("LIST")) {
}
else {
fprintf(fd, "502 Command not implemented.\n"); fflush(fd);
printf("Comando : %s %s\n", command, arg);
printf("Error interno del servidor\n");
}
}
fclose(fd);
return;
};
Error code 88 is ENOTSOCK meaning that your tried to do a socket operation on "not a socket".
The offending line, I believe is:
send(data_socket,buffer,sent_datas,0);
It looks like in your RETR section you never set data_socket to a valid socket with your connect_TCP function, as you did in PORT. Are you certain that data_socket is a valid fd when you call your RETR function?