c語言socket雙向通信+一服務(wù)端對多客戶端通信
[導(dǎo)讀]任務(wù)在完成socket客戶端對服務(wù)端的通信以后,又讓我搞雙向通信,然后又是讓我用app去控制gpio口的高低變化.努力了三天,從socket的學(xué)習(xí)到多線程的學(xué)習(xí),一步一步的完成了任務(wù),測試從app到服
任務(wù)
在完成socket客戶端對服務(wù)端的通信以后,又讓我搞雙向通信,然后又是讓我用app去控制gpio口的高低變化.努力了三天,從socket的學(xué)習(xí)到多線程的學(xué)習(xí),一步一步的完成了任務(wù),測試從app到服務(wù)器在到小板上的數(shù)據(jù)流全部打通.下班之前記錄一下.
思路
socket雙向通信使用的方法是服務(wù)端開啟服務(wù)等客戶端連接上以后開辟一個線程,然后把客戶端套接字client_sockfd傳遞過去,輸入數(shù)據(jù)后發(fā)送給客戶端.反之亦然.
一服務(wù)端對多客戶端的通信采用select.參考博客見:http://blog.csdn.net/ctrl_qun/article/details/52524086 作者寫的非常棒,講解的也很全面,繼續(xù)研讀中.對它的代碼進(jìn)行了部分改進(jìn).添加了對客戶端上傳的數(shù)據(jù)下發(fā)到所有的客戶端,這個是我項目中的需求.然后添加了一個頭文件.因為有些即用即初始化的參數(shù),所以需要使用c99的標(biāo)準(zhǔn)去編譯.
gcc?-std=c99?client.c?-o?client
雙向通信
/*代碼里面有部分我對驅(qū)動程序的相關(guān)控制*/ /*socket端*/ #include#include#include#include#include#include#include#include#include#include#include#define?MAXBUF?512 #define?DEV_IOC_MAGIC?'0xee'?//定義幻數(shù) #define?DEV_IOCPRINT??_IO(DEV_IOC_MAGIC,?1) #define?DEV_IO_HIGH???_IO(DEV_IOC_MAGIC,?2) #define?DEV_IO_LOW????_IO(DEV_IOC_MAGIC,?3) #define?DEV_IOC_MAXNR?3 char?send_buf[MAXBUF+1]; int?fd; void?*thread(void?*x)?? {??? ????int?cmd; ????char?buf[BUFSIZ]; ????int?new_fd?=?*((int*)x); ????while(recv(new_fd,buf,BUFSIZ,0)>0) ????{ ????????//int?len=recv(new_fd,buf,BUFSIZ,0); ????????if(strcmp(buf,"1")==0) ????????{ ????????????printf("n"); ????????????cmd?=?DEV_IO_HIGH; ????????????if?(ioctl(fd,?cmd)?<?0) ????????????{ ????????????????printf("Call?cmd?DEV_IO_HIGH?failn"); ????????????} ????????????printf("NOW,GPIO?is?High.n"); ????????} ????????if(strcmp(buf,"0")==0) ????????{ ????????????printf("n"); ????????????cmd?=?DEV_IO_LOW; ????????????if?(ioctl(fd,?cmd)?<?0) ????????????{ ????????????????printf("Call?cmd?DEV_IO_LOW?failn"); ????????????} ????????????printf("NOW,GPIO?is?Low.n"); ????????} ????????printf("client:received:%sn",buf); ????} ????/*while(1) ????{ ????????bzero(send_buf,?MAXBUF?+?1); ????????scanf("%s",send_buf); ????????send(new_fd,?send_buf,?strlen(send_buf),?0);?//第?4?步?向套接字中寫入字符串 ????}*/ ????return?NULL;?? } void?open_dev() { ????fd?=?open("/dev/dsx",?O_RDWR); ????if(fd?<?0) ????????printf("/dev/dsx?is?open?fail!n"); } int?main(int?argc,?char?*argv[]) { ????int?client_sockfd; ????int?len; ????struct?sockaddr_in?remote_addr;?//服務(wù)器端網(wǎng)絡(luò)地址結(jié)構(gòu)體 ????char?buf[BUFSIZ];??//數(shù)據(jù)傳送的緩沖區(qū) ????memset(&remote_addr,0,sizeof(remote_addr));?//數(shù)據(jù)初始化--清零 ????remote_addr.sin_family=AF_INET;?//設(shè)置為IP通信 ????remote_addr.sin_addr.s_addr=inet_addr("0.0.0.0");//服務(wù)器IP地址 ????remote_addr.sin_port=htons(8000);?//服務(wù)器端口號 ????open_dev(); ????/*創(chuàng)建客戶端套接字--IPv4協(xié)議,面向連接通信,TCP協(xié)議*/ ????if((client_sockfd=socket(PF_INET,SOCK_STREAM,0))<0) ????{ ????????perror("socket"); ????????return?1; ????} ????/*將套接字綁定到服務(wù)器的網(wǎng)絡(luò)地址上*/ ????if(connect(client_sockfd,(struct?sockaddr?*)&remote_addr,sizeof(struct?sockaddr))<0) ????{ ????????perror("connect"); ????????return?1; ????} ????printf("connected?to?servern"); ????//len=recv(client_sockfd,buf,BUFSIZ,0);//接收服務(wù)器端信息 ????//?????buf[len]='