过去10天我正在使用蓝牙插座。我必须在客户端和服务器模式之间切换。我写了一段代码。我能够正常发送数据包,但当我在聆听模式工作时,我遇到了两个问题。 1.接受处于阻止模式,因此无法返回发送模式。 2.我使用FNCTL()
使套接字无阻塞但现在问题就是在两种模式之间完全切换,但它没有收到任何数据包。我的代码如下: -
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_lib.h>
#include <bluetooth/l2cap.h>
#define MAXPROFILES 2
int SetTimer(struct timeval *tv, time_t sec)
{
gettimeofday(tv,NULL);
tv->tv_sec+=sec;
return 1;
}
void start_scan()
{
struct sockaddr_l2 addr1 = { 0 };
int s=0,h, status,f,contacted;
int search=1;
char *message = "hello!";
char dest[18] = "01:23:45:67:89:AB";
struct neighbor
{
char peer[19];
} p[h];
unsigned char buf[1024];
inquiry_info *devices = NULL;
int max_rsp, num_rsp;
int dev_id, sock, len, flags,cmp;
int x=0,i;
char addr[19] = { 0 };
char name[248] = { 0 };
dev_id = hci_get_route(NULL);
sock = hci_open_dev( dev_id );
if (dev_id < 0 || sock < 0)
{
perror("opening socket");
exit(1);
}
len = 3;
max_rsp = 255;
flags = IREQ_CACHE_FLUSH;
devices = (inquiry_info*)malloc(max_rsp * sizeof(inquiry_info));
struct timeval tv;
SetTimer(&tv,15);
while(search == 1)
{ //fprintf(stderr,"\t%d \n", time);
num_rsp = hci_inquiry(dev_id, len, max_rsp, NULL, &devices, flags);
fprintf(stderr,"%s (%d) %d\n", "done scanning, found ", j, num_rsp);
if( num_rsp < 0 ) perror("hci_inquiry");
for (i = 0; i < num_rsp; i++)
{
ba2str(&(devices+i)->bdaddr, addr);
fprintf(stderr,"\t%s \n", addr);
cmp= strncmp(addr,"10:2E:AF:EB:33:BD",8);
if(cmp==0)
{
fprintf(stderr,"\t%s \t%d\n", addr,cmp);
for(f=0;f<=h;f++)
{
if(p[f].peer[18]==addr[19])
contacted=1;
}
if(contacted==1)
{
contacted=0;
continue;
}
s = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
// set the connection parameters (who to connect to)
addr1.l2_family = AF_BLUETOOTH;
addr1.l2_psm = htobs(0x1001);
strncpy(dest, addr, 18);
str2ba( dest, &addr1.l2_bdaddr );
// connect to server
status = connect(s, (struct sockaddr *)&addr1, sizeof(addr1));
// send a message
if( status == 0 )
{
status = write(s, "hello", 10);
h++;
p[h].peer[18]=addr[19];
}
if( status < 0 )
{
perror("uh oh");
}
}
} // for
x++;
if(!(x%2))
flags = IREQ_CACHE_FLUSH;
else
flags = 0x00;
if (CheckTimer(&tv,5)==1)
{ //close(sock);
fprintf(stderr,"listen....\n");
start_listen(s);
}
}
}
int start_listen(int s)
{ struct sockaddr_l2 addr1 = { 0 },rem_addr = { 0 };;
fd_set fds;
int client, bytes_read,sock_flags;
char buf1[1024] = {0};
socklen_t opt = sizeof(rem_addr);
struct timeval tv;
addr1.l2_family = AF_BLUETOOTH;
addr1.l2_bdaddr = *BDADDR_ANY;
addr1.l2_psm = htobs(0x1001);
sock_flags=fcntl(s,F_GETFL,0);
fcntl(s,F_SETFL,sock_flags | O_NONBLOCK);
bind(s, (struct sockaddr *)&addr1, sizeof(addr1));
SetTimer(&tv,15);
// put socket into listening mode
while(!0)
{
listen(s, 1);
//fprintf(stderr,"I am listening....\n");
// accept one connection
client = accept(s, (struct sockaddr *)&rem_addr, &opt);
//fprintf(stderr,"I failed....\n");
FD_ZERO(&fds);
FD_SET(s,&fds);
ba2str( &rem_addr.l2_bdaddr, buf1 );
memset(buf1, 0, sizeof(buf1));
// read data from the client
bytes_read = read(client, buf1, sizeof(buf1));
if( bytes_read > 0 ){
printf("received [%s]\n", buf1);
fprintf(stderr, "accepted connection from %s\n", buf1);
}
close(client);
if (CheckTimer(&tv,5)==1)
{fprintf(stderr,"done listening...");
SetTimer(&tv,15);
return 1;
}
}//while of the listening mode
}
int CheckTimer(struct timeval *tv, time_t sec)
{
struct timeval ctv;
gettimeofday(&ctv,NULL);
if((ctv.tv_sec > tv->tv_sec))
{
gettimeofday(tv,NULL);
tv->tv_sec+=sec;
return 1;
}
else return 0;
}
int main(int argc, char **argv)
{start_scan();
}
答案 0 :(得分:0)
我能够通过在绑定之前在侦听模式下再次输入以下命令来解决问题。
s = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
但现在问题是我的close(client)
无效。我无法关闭客户端并收听新客户端。有谁知道为什么?
答案 1 :(得分:0)
根本不需要打开服务器套接字! (除非您的远程设备正在做某事非常奇数!!)套接字可用于发送 和 接收 - 无论是客户端套接字还是服务器套接字。
删除所有执行listen + accept等操作的代码,然后写入并读取原始(客户端)套接字。(完成的操作:“connect(s,
...”)
如果您的远程设备确实需要两个不同的连接。使用新变量来保存套接字句柄并且没有服务器套接字句柄覆盖原始客户端句柄。