I have written a small bluetooth server and client progrem using winsock
I am not able to figure out why the client is not getting connected to the server. Both are running in different pcs and
both are paired through bluetooth.
The server code is
void server()
{
SOCKET server_socket = socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM), new_socket;
if (server_socket == INVALID_SOCKET)
{
cout << "socket creation failed...Error code : " << WSAGetLastError() << endl;
Sleep(2000);
return;
}
cout << "socket created" << endl;
SOCKADDR_BTH sa, sa2;
int channel = 0, len=sizeof(sa2);
memset(&sa, 0, sizeof(SOCKADDR_BTH));
sa.addressFamily = AF_BTH;
sa.port = channel & 0xff;
//bind
if (bind(server_socket, (SOCKADDR *)&sa, sizeof(sa)))
{
cout << "Binding failed...Error code : " << WSAGetLastError() << endl;
closesocket(server_socket);
Sleep(2000);
return;
}
cout << "binding done" << endl;
cout << "\nWaiting for client" << endl;
listen(server_socket, 3);
new_socket = accept(server_socket, (sockaddr *)&sa2, &len);
cout<<"connection accepted";
}
The client code is
void client()
{
SOCKET client_socket = socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
int channel = 0;
BTH_ADDR bt_addr;
char* server_address = "34:02:86:26:c1:62";
if (client_socket == INVALID_SOCKET)
{
cout << "socket creation failed...Error code : " << WSAGetLastError() << endl;
Sleep(2000);
return;
}
cout << "socket created" << endl;
if (str2ba(server_address, &bt_addr) == 1)
{
cout << "address conversion error..." << endl;
Sleep(2000);
return;
}
SOCKADDR_BTH sa;
sa.addressFamily = AF_BTH;
sa.port = channel & 0xff;
sa.btAddr = bt_addr;
cout << "\nconnecting..." << endl;
if (connect(client_socket, (sockaddr *)&sa, sizeof(sockaddr)))
{
cout << "Error in connecting...Error code : " << WSAGetLastError() << endl;
closesocket(client_socket);
Sleep(2000);
return;
}
cout << "\nConnected" << endl;
Sleep(2000);
}
int str2ba(char *str_bt_addr, BTH_ADDR *bt_addr)//for converting string to bluetooth address
{
unsigned int addr[6];
if (sscanf_s(str_bt_addr, "%02x:%02x:%02x:%02x:%02x:%02x",
&addr[0], &addr[1], &addr[2], &addr[3], &addr[4], &addr[5]) != 6)
{
return 1;
}
*bt_addr = 0;
BTH_ADDR tmpaddr;
int i;
for (i = 0;i < 6;++i)
{
tmpaddr = (BTH_ADDR)(addr[i] & 0xff);
*bt_addr = ((*bt_addr) << 8) + tmpaddr;
}
return 0;
}
Why are these not getting connected? What am I missing?
Please help me.
Thanks in advance for any help.
In my short Bluetooth experience, the problem is normally somewhere in the SOCKADDR_BTH declarations.
I hard coded the MAC Address of each Endpoint: "38:2D:E8:B9:FA:EB" in Hex
RemoteEndPoint.btAddr = BTH_ADDR(0x382DE8B9FAEB);
Also make sure your Ports are the same on each Endpoint, I used:
RemoteEndPoint.port = 0;
and
LocalEndpoint.port = 0;
I have some code here: C++ WinSock Bluetooth Connection - AT Command - Error Received where I have an issue also.
Bluetooth is not as easy as some may think, thus the lack of answers received by the OP's
Related
I am doing a server and client programs in C++ on Debian Linux
Below is the server:
void MonitoringServer::serve() {
int serverSocketFd, childSocketFd;
int clientAddrLen;
struct sockaddr_in serverAddr, clientAddr;
if ((serverSocketFd = socket(AF_INET, SOCK_STREAM, 6)) < 0) {
std::cout << "could not create socket. exiting..." << std::endl;
} else {
std::cout << "socket created with file descriptor : " << serverSocketFd << std::endl;
bzero((char*)&serverAddr, sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = inet_addr("192.168.1.92");
serverAddr.sin_port = htonl(15500);
if (bind(serverSocketFd, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0) {
std::cout << "error binding server socket. exiting..." << std::endl;
stop = true;
} else {
std::cout << "socket file descriptor bound to the specified address" << std::endl;
}
int listenResult = listen(serverSocketFd, 10);
if (listenResult < 0) {
std::cout << "listen returned a negative value" << std::endl;
stop = true;
} else {
std::cout << "server socket is listening" << std::endl;
}
while (!stop) {
std::cout << "going to accept the next client connection" << std::endl;
childSocketFd = accept(serverSocketFd, (struct sockaddr*)&clientAddr, (socklen_t*)&clientAddrLen);
if (childSocketFd < 0) {
std::cout << "error accepting connections. exiting..." << std::endl;
switch (errno) {
case EBADF : std::cout << "socket not valid file descriptor" << std::endl; break;
case ECONNABORTED : std::cout << "connection aborted" << std::endl; break;
case EFAULT : std::cout << "address param not in writable part of address space" << std::endl; break;
case EINTR : std::cout << "accept() terminated by a signal" << std::endl; break;
case EINVAL : std::cout << "socket is not wiling to accept connections" << std::endl; break;
case EMFILE : std::cout << "The per-process descriptor table is full" << std::endl; break;
case ENOMEM : std::cout << "No memory available to complete the operation" << std::endl; break;
case ENOTSOCK : std::cout << "Descriptor is not a socket" << std::endl; break;
case EOPNOTSUPP : std::cout << "socket is not of type SOCK_STREAM and thus does not accept connections" << std::endl; break;
case EWOULDBLOCK : std::cout << "socket is non-blocking and no connections are present to be accepted" << std::endl; break;
default : std::cout << "unknown error in accept call : " << errno << std::endl;
}
stop = true;
}
pthread_attr_t attr;
pthread_t threadID;
int threadOpRetValue;
if (!stop) {
threadOpRetValue = pthread_attr_init(&attr);
if (threadOpRetValue < 0) {
std::cout << "error creating client handling thread. exiting..." << std::endl;
stop = true;
}
}
if (!stop) {
threadOpRetValue = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
if (threadOpRetValue < 0) {
std::cout << "error configuring client handling thread. exiting..." << std::endl;
stop = true;
}
}
if (!stop) {
threadOpRetValue = pthread_create(reinterpret_cast<pthread_t *>(threadID), &attr,
&MonitoringServer::handle, &childSocketFd);
if (threadOpRetValue < 0) {
std::cout << "error creating the client socket worker thread. exiting..." << std::endl;
stop = true;
}
}
}
}
}
When I run the program, it blocks on the accept call, but I neither see the process on the netstat -a output, and the below client returns a connection refused error code.
int main(int argc, char **argv) {
std::cout << "starting client..." << std::endl;
int socketFD;
struct sockaddr_in serverAddress;
bool stop = false;
// open the socket
bzero((char*)&serverAddress, sizeof(serverAddress));
serverAddress.sin_family = AF_INET;
serverAddress.sin_addr.s_addr = inet_addr(argv[1]);
serverAddress.sin_port = htons(atoi(argv[2]));
if ((socketFD = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
std::cout << "error creating the socket. exiting..." << std::endl;
stop = true;
}
int connRetValue;
if (!stop && (connRetValue = connect(socketFD, (struct sockaddr*)&serverAddress, sizeof serverAddress)) < 0) {
std::cout << "error code " << connRetValue << std::endl;
std::cout << "error connecting to the server. exiting..." << std::endl;
connRetValue = errno;
switch (connRetValue) {
case EACCES : std::cout << "broadcast address specified" << std::endl; break;
case EADDRINUSE : std::cout << "address in use" << std::endl; break;
case EADDRNOTAVAIL : std::cout << "address not available" << std::endl; break;
case EAFNOSUPPORT : std::cout << "wrong address family" << std::endl; break;
case EBADF : std::cout << "bad socket descriptor" << std::endl; break;
case ECONNREFUSED : std::cout << "connection refused" << std::endl; break;
case EFAULT : std::cout << "address out of process address space" << std::endl; break;
case EHOSTUNREACH : std::cout << "target host is unreachable" << std::endl; break;
case EINPROGRESS : std::cout << "connection in progress in nonblocking socket" << std::endl; break;
case EINTR : std::cout << "execution interrupted by a signal" << std::endl; break;
case EISCONN : std::cout << "socket already connected" << std::endl; break;
case ENETDOWN : std::cout << "network interface mal-function" << std::endl; break;
case ENETUNREACH : std::cout << "network unreachable" << std::endl; break;
case ENOBUFS : std::cout << "unable to allocate buffer in memory" << std::endl; break;
case ENOTSOCK : std::cout << "descriptor is not a socket" << std::endl; break;
case EOPNOTSUPP : std::cout << "socket is listening. operation not allowed" << std::endl; break;
case EPROTOTYPE : std::cout << "address of different type than the socket" << std::endl; break;
case ETIMEDOUT : std::cout << "timeout" << std::endl; break;
case ECONNRESET : std::cout << "remote host reset the connection" << std::endl; break;
default : std::cout << "unknown error code : " << connRetValue << std::endl;
}
stop = true;
}
if (!stop) {
char* message = "ola bichinhos";
write(socketFD, message, strlen(message)*sizeof(char));
}
close(socketFD);
return 0;
}
I am starting to suspect of selinux imposing security restrictions on what my processes can do, but I am not sure.
Can someone tell me if there is anything wrong with this code before I start to investigate SE linux ?
I was building the address port with the wrong conversion function.
I was using htonl and it should be htons.
In the complete code (see below), at some point (after N iterations) the consumer (function executionServiceHandler while (inService_) is entered, despite inService_ having been changed (in the same thread) [or so it seems from log output].
I have as far as possible tried to guard std::cout as well, although I'm not sure this is necessary.
Could you perhaps crit the code. I know strictly speaking I don't need to use StopServiceCmd to let the thread complete, but in my mind I can't see why it shouldn't work.
Also, I could have used std::function, but the example is simplified from original.
I could add that I tested this on GCC (latest), after the original example failed on VCC (2017)
Code follows (EDIT - now using std::function:
#include <thread>
#include <functional>
#include <mutex>
#include <iostream>
#include <queue>
#include <sstream>
#include <condition_variable>
class ThreadCmdConsumer
{
public:
using Guard = std::lock_guard<std::mutex>;
using UniqueLock = std::unique_lock<std::mutex>;
ThreadCmdConsumer()
: inService_(),
executionServiceThread_(std::bind(&ThreadCmdConsumer::executionServiceHandler, this))
{
//Wait while thread does not exist...
UniqueLock lock(cmdQMutex_);
while (!inService_) {
conditional_.wait(lock);
}
std::cout << std::hex << this << " constructed and consumer waiting..." << std::endl;
}
~ThreadCmdConsumer() {
static std::size_t nth = 0;
{
UniqueLock lock(cmdQMutex_);
std::cout << "destructing (" << std::dec << nth++ << "): " << std::hex << this << std::endl;
}
process([this](){
//Note: inService_ can only be changed in consumer thread...
inService_ = false;
std::cout << "consumer_->inService state: " << inService_ << std::endl;
});
UniqueLock lock(cmdQMutex_);
std::cout << "producer " << std::hex << this << " destructor has lock" << std::endl;
while (inService_) {
std::cout << "producer " << std::hex << this << " destructor in service, entering wait" << std::endl;
conditional_.wait(lock);
std::cout << "producer " << std::hex << this << " destructor exited wait - has lock" << std::endl;
}
// Join will always succeed as result of StopServiceCmd that sets inService to false
// (in its own thread context). Once join completes, we are certain of executionServiceHandler
// exiting normally.
std::cout << "produces " << std::hex << this << " destructor joining" << std::endl;
lock.unlock();
try {
executionServiceThread_.join();
}
catch (const std::system_error& ex) {
UniqueLock lock(cmdQMutex_);//for cout
std::cout << "Exception during join" << ex.what() << std::endl;
abort();
}
}
void executionServiceHandler()
{
{ //Starts the service...
UniqueLock lock(cmdQMutex_);
inService_ = true;
lock.unlock();
conditional_.notify_one();
}
try {
UniqueLock lock(cmdQMutex_);
while (inService_) {
std::cout << "consumer " << std::hex << this << " has lock" << std::endl;
// Catering for spurious wake-ups too, hence while...
while (cmdQ_.empty()) {
std::cout << "consumer " << std::hex << this << " waiting" << std::endl;
conditional_.wait(lock);
std::cout << "consumer " << std::hex << this << " woken" << std::endl;
}
//Now we have the lock, and queue most certainly not empty
auto cmd = std::move(cmdQ_.front());
cmdQ_.pop();
//###lock.unlock(); // Don't want to be locked while executing... removed conservatively
(cmd)();
}
std::cout << "consumer " << std::hex << this << " execution complete" << std::endl;
}
catch(const std::exception& ex) {
std::cerr << "Unexpected " << ex.what() << std::endl;
abort();
}
//Not in service - notify when we've left (then we can truly join...)
conditional_.notify_one();
}
void process(std::function<void()>&& cmd)
{
UniqueLock lock(cmdQMutex_);
std::cout << "producer " << std::hex << this << " has lock" << std::endl;
bool notificationRequired = cmdQ_.empty();
cmdQ_.push(move(cmd));
if (notificationRequired) {
std::cout << "producer " << std::hex << this << " notifying" << std::endl;
lock.unlock();
conditional_.notify_one();
}
else {
std::cout << "producer " << std::hex << this << " not notifying" << std::endl;
}
}
private:
bool inService_;
std::queue<std::function<void()>> cmdQ_;
std::condition_variable conditional_;
std::mutex cmdQMutex_;
std::thread executionServiceThread_;
};
typedef std::function<void(const std::string&)> Handler;
struct ThreadOwner
{
ThreadCmdConsumer executor_;
// Do it done in the context of executor....
void doIt(const Handler& handler)
{ }
};
int main()
{
std::cout << "Program started" << std::endl;
//Sometimes deadlocks on thread being killed
for (int i = 0; i < 1000; ++i) {
auto handler = [](const std::string&){};
{
ThreadOwner owner;
owner.executor_.process([&handler, &owner]() {
owner.doIt(handler);
});
}
}
}
void ca_time(int *arr,int &len_) //the variable len_'s value always is 0
{
cout << "You only got five seconds to type the number 1~5,,ready go,,\n";
_sleep(5000);
cout << "Sorry time out!!\n";
cout << "Ok, here is your greads:\n";
for(int i = 0; i < len_; i ++)
{
cout << arr[i] << " ";
}
cout << endl;
cout <<"-->" << len_ << endl;
return;
}
void fun_type(int *arr,int &len_)
{
memset(arr,'\0',sizeof(arr));
for(; len_ < 5; len_ ++)
{
cin >> arr[len_];
}
}
int main()
{
int arr[100];
int len = 0;
thread time(ca_time,arr,len);
time.detach();
fun_type(arr,len);
system("pause");
return 0;
}
But it work when changed the quote to the address(point variable).Why?
Somebody say that's a IED's bug?But I don't think so .So What the hell?
Using Windows Management Instrumentation (WMI) in VC++ we can find the SystemInfo like System Name and other properties.
Example for GetComputerName :
BOOL WINAPI GetComputerName(
_Out_ LPTSTR lpBuffer,
_Inout_ LPDWORD lpnSize
);
There are 3 printers attached in my system 1 thermal and 2 Shared printers ,
How can i get the information about printer which is offline ?
How can i classify/list printers based on their status ?
Thanks
See also EnumPrinters
DWORD flags = PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS;
DWORD bufsize, printerCount;
DWORD level = 2; //2 is for PRINTER_INFO_2
::EnumPrinters(flags, NULL, level, NULL, 0, &bufsize, &printerCount);
if (bufsize)
{
BYTE* buffer = new BYTE[bufsize];
::EnumPrinters(flags, NULL, level, buffer, bufsize, &bufsize, &printerCount);
if (bufsize && printerCount)
{
const PRINTER_INFO_2* info = (PRINTER_INFO_2*)buffer;
for (DWORD i = 0; i < printerCount; i++)
{
if (info->pServerName) cout << "pServerName: " << info->pServerName << endl;
if (info->pPrinterName) cout << "pPrinterName: " << info->pPrinterName << endl;
if (info->pShareName) cout << "pShareName: " << info->pShareName << endl;
if (info->pPortName) cout << "pPortName: " << info->pPortName << endl;
if (info->Attributes & PRINTER_ATTRIBUTE_LOCAL) cout << "[local]\n";
if (info->Attributes & PRINTER_ATTRIBUTE_NETWORK) cout << "[network]\n";
wcout << "status: " << info->Status << endl;
if (info->Status & PRINTER_STATUS_ERROR) cout << "status: error\n";
wcout << endl;
info++;
}
}
delete[] buffer;
}
i've got a following problem: i have a epoll code which receives connections:
while (1) {
int nfds = epoll_wait(epollfd, events, 4096, -1);
if (nfds == -1) {
if (errno == EINTR)
continue;
perror("epoll_wait");
exit(EXIT_FAILURE);
}
for (int i = 0; i < nfds; i++) {
if (events[i].data.fd == server_sock) {
client_sock = accept(server_sock,
(struct sockaddr *)&client_name,
(socklen_t *)(&client_name_len));
if (client_sock == -1) //server overloaded
continue;
ev.events = EPOLLIN | EPOLLERR;
#ifdef CORE_NONBLOCKING_SOCKETS
Arch::set_nonblocking(client_sock);
ev.events |= EPOLLET; //input data and connection closing
#endif
#ifdef EPOLLRDHUP
ev.events |= EPOLLRDHUP ;//
#else
//for old libraries
ev.events |= EPOLLHUP;//
#endif
ev.data.fd = client_sock;
if (epoll_ctl(epollfd, EPOLL_CTL_ADD, client_sock, &ev) == -1) {
perror("epoll_ctl: client_socket");
exit(EXIT_FAILURE);
}
accept_request(client_sock);
} else {
#ifdef EPOLLRDHUP
if (events[i].events & EPOLLRDHUP) {
std::cout << "EPOLLRDHUP on " << events[i].data.fd << std::endl;
listener->disconnectDriver(events[i].data.fd);
}
#else
if (events[i].events & EPOLLHUP) {
std::cout << "EPOLLHUP on " << events[i].data.fd << std::endl;
listener->disconnectDriver(events[i].data.fd);
}
#endif
if (events[i].events & EPOLLIN) {
std::cout << "debug EPOLLIN on " << events[i].data.fd << std::endl;
accept_request(events[i].data.fd);
}
if (events[i].events & EPOLLERR) {
std::cout << "debug EPOLLERR on " << events[i].data.fd << std::endl;
listener->disconnectDriver(events[i].data.fd);
}
}
}
when i received input connection i trying to read all buff data:
void get_all_buf(int sock, std::string & inStr) {
int n = 1;
int total = 0;
char c;
char temp[1024*1024];
bzero(temp, sizeof(temp));
do {
#ifdef CORE_NONBLOCKING_SOCKETS
timespec time_to_wait;
time_to_wait.tv_nsec = 10000000;
time_to_wait.tv_sec = 0;
timespec tm;
time_t begin = time(NULL);
do {
#endif
n = recv(sock, &temp[total], sizeof(temp), 0);
#ifdef CORE_NONBLOCKING_SOCKETS
nanosleep(&time_to_wait, &tm);
time_t end = time(NULL);
if ((end - begin) > MAX_CLIENT_TIME) {
inStr = std::string();
return;
}
} while (n < 0 && errno == EAGAIN); //nonblocking sockets in edge-triggered mode
#endif
if (n > 0) {
total += n;
} else if (n == 0) {
//TODO: error handling
//debug
std::cout << "possibly no one byte was received" << std::endl;
break;
} else if (n < 0) {
//TODO: error handling
//debug
std::cout << "error while receiving data" << std::endl;
if (errno == EBADF) {
std::cout << "recv returns with EBADF: " << strerror(errno) << std::endl;
} else if (errno == EFAULT) {
std::cout << "recv returns with EFAULT: " << strerror(errno) << std::endl;
} else if (errno == EINTR) {
std::cout << "recv returns with EINTR: " << strerror(errno) << std::endl;
} else if (errno == EINVAL) {
std::cout << "recv returns with EINVAL: " << strerror(errno) << std::endl;
}
//end debug
break;
}
} while (!strstr(temp, "</packet>"));
inStr = temp;
};
within accept_request function. but sometime i get following in my debug output:
packet type='connect'
size of vector<Driver> in getDriversWithMoney is 1
epoll_wait detected activity of 164 counter i = 0 nfds = 1
EPOLLRDHUP on 164
disconnectDriver (fd = 164)
driver 1 disconnected
debug EPOLLIN on 164
error while receiving data
recv returns with EBADF: Invalid file descriptor
which means that someone was connected first than disconnected and when he's trying to connect again recv returns EBADF. what i did wrong? please help me.
P.S. on EPOLLRDHUP i just close file descriptor. epoll man says it's ok, because epoll removes closed fd from epoll_wait queue by itself.
When the remote host closes the socket, epoll() reports both a HUP and an EPOLLIN for the file descriptor.
You check for EPOLLRDHUP first, and close the socket; then you check for EPOLLIN, find that too, and try to call recv(). Since the socket has been closed, the file descriptor is no longer valid, and you get EBADF (the closed socket is removed from the epoll set, so subsequent epoll_wait() calls won't return it; but for the epoll_wait() that has already returned it's too late - the EPOLLIN is already waiting in your events[i].
You need to stop checking for events after you call disconnectDriver() (if it closed the file descriptor):
if (events[i].events & EPOLLRDHUP) {
std::cout << "EPOLLRDHUP on " << events[i].data.fd << std::endl;
listener->disconnectDriver(events[i].data.fd);
continue;
}