蓝牙编程-l2cap协议层的c/s程序

来源:互联网 发布:windows下使用webpack 编辑:程序博客网 时间:2024/06/15 05:44

导读:
  昨天晚上完成了使用BlueZ协议栈中的lib实现rfcomm层连接的程序,并且移植到了arm-linux上运行通过.程序实现了客户端发送字符串在服务端控制台显示.但是在输入大量的字符时会出现没有响应的情况.看了下书估计和socket中的MTU(Max Transportion Unit)有关系,但也没有继续去试验了,应为在我的应用中一般不会直接使用rfcomm作为连接协议,而是使用l2cap协议.所以今天就来试试l2cap协议方式的socket连接. 以下为客户端的程序:
  #include
  #include
  #include
  #include
  #include
  #include
  int main( int argc , char **argv)
  {
  struct sockaddr_l2 addr={0};
  int s,status;
  char *dest,*buf; //="00:11:67:32:61:62";
  if(argc==2)
  {
  dest=argv[1];
  }
  else
  {
  printf("useage:client addr/n");
  exit(1);
  }
  // a l l o c a t e a s oc k e t
  s=socket(PF_BLUETOOTH,SOCK_SEQPACKET,BTPROTO_L2CAP);
  if(s<0)
  {
  perror("create socket error");
  exit(1);
  }
  // s e t the conne c t ion parameter s (who to connect to )
  addr.l2_family=AF_BLUETOOTH;
  addr.l2_psm=htobs(0x1001);
  str2ba(dest,&addr.l2_bdaddr);
  // connect to s e r v e r
  printf("connectting.../n");
  status=connect(s,(struct sockaddr *)&addr,sizeof(addr));
  // send a message
  if(status==0){
  printf("scuess!/n");
  status=write(s,"hello!",6);
  
  do{
  scanf("%s",buf);
  status=write(s,buf,strlen(buf));
  if(status<0) perror("uh oh");
  }while(strcmp(buf,"goodbye")!=0);
  }
  else
  {
  printf("Failed!/n");
  }
  close(s);
  return 0;
  }
  以下为服务端的程序:
  #include   #include
  #include
  #include
  #include
  #include
  int main (int argc,char **argv)
  {
  struct sockaddr_l2 loc_addr ={0},rem_addr={0};
  char buf[1024] ={0};//,*addr;
  int s,client, bytes_read,result;
  int opt = sizeof(rem_addr);
  
  //allocate socket
  printf("Creating socket.../n");
  s =socket(PF_BLUETOOTH,SOCK_SEQPACKET,BTPROTO_L2CAP);
  if(s<0)
  {
  perror("create socket error");
  exit(1);
  }
  else
  {
  printf("success!/n");
  }
  // bind socket to port 1 of the first available
  // local bluetooth adapter
  loc_addr.l2_family=AF_BLUETOOTH;
  loc_addr.l2_bdaddr=*BDADDR_ANY;
  loc_addr.l2_psm=htobs(0x1001);
  
  printf("Binding socket.../n");
  result=bind(s,(struct sockaddr *)&loc_addr, sizeof(loc_addr));
  if(result<0)
  {
  perror("bind socket error:");
  exit(1);
  }
  else
  {
  printf("success!/n");
  }
  // put socket into listening mode
  /*result=ba2str(&loc_addr.rc_bdaddr,addr);
  if(result<0)
  {
  perror("addr convert error");
  exit(1);
  }
  printf("local addr is:%s/n",addr);*/
  printf("Listen... ");
  result=listen(s,1);
  if(result<0)
  {
  printf("error:%d/n:",result);
  perror("listen error:");
  exit(1);
  }
  else
  {
  printf("requested!/n");
  }
  // ac c ept one conne c t ion
  printf("Accepting.../n");
  client= accept(s,(struct sockaddr *)&rem_addr,&opt);
  if(client<0)
  {
  perror("accept error");
  exit(1);
  }
  else
  {
  printf("OK!/n");
  }
  ba2str(&rem_addr.l2_bdaddr,buf);
  fprintf(stderr,"accepted connection from %s /n",buf);
  memset(buf,0,sizeof(buf));
  // read data from the client
  while(1)
  {
  bytes_read = read(client,buf,sizeof(buf));
  if(bytes_read>0){
  printf("received[%s]/n",buf);
  if(strcmp(buf,"goodbye")==0)
  exit(1);
  memset(buf,0,bytes_read);
  }
  }
  //close connection
  close(client);
  close(s);
  return 0 ;
  }
  整个程序和rfcomm协议下的socket程序区别不是很大,只是在创建socket的时候使用协议和数据结构有所不同.在使用中发现在默认MTU的设置下,能够一次传输的字符串长度明显长于rfcomm模式下,且较为稳定.
  但是在默认情况下,这样创建的连接并不能算是可信赖的连接.下次再来研究下如何创建一个可信赖的连接./

本文转自
http://blog.csdn.net/ifq/archive/2006/06/08/780481.aspx

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/yingfox/archive/2007/11/11/1878586.aspx