上一篇博客写了串口通信,实现了串口收发数据及串口参数的设置等基本功能,实际情况中串口经常被用到,所以可以考虑将其打包封装一下,需要用的时候直接在主函数里直接调用即可,工程量会减少很多。串口函数打包实际上就是将串口的参数放在结构体里面,通过结构体指针将参数传给函数。每次调用函数时只需要一个参数,会方便很多。我最近在做串口转socket的时候就用到了,刚开始我只写了一个简单的串口函数,实现了数据的收发。但是我发现如果要通过socket转发出去,代码会很长,而且很不方便。打包了以后你就会发现,只需要在主函数中调用打包好的几个函数即可。
串口转socket实际上就是将串口收到的数据同socket发送出去,因为之前做过socket网络通信,只要能将串口编程搞会还是没有什么难度的。我看到几篇博客都是通过服务器端将串口收到的数据发送给客户端,客户端连接服务器端就会收到串口数据。我觉得这应该是业务逻辑的问题,就要看你自己想要什么样的功能,根据自己的需求来判断是客户端发给服务器或者是服务器发给客户端,我觉得两种逻辑都可以实现。我实现的是客户端发给服务器。下面为客户端部分代码:
42 int main(int argc,char **argv)
43 {
44 int ch;
45 int rv;
46 int connfd;
47
48
49 int Port=0;
50
51 char data_buf[64];
52 char rbuf[64];
53 char *server_ip=NULL;
54 com_port *opt=InitComport();
55
56
57 struct option opts[]={
58 {"ipaddr",required_argument,NULL,'i'},
59 {"Port",required_argument,NULL,'P'},
60 {"Device",required_argument,NULL,'D'},
61 {"baudrate",optional_argument,NULL,'b'},
62 {"databit",optional_argument,NULL,'d'},
63 {"stopbit",optional_argument,NULL,'s'},
64 {"parity",optional_argument,NULL,'p'},
65 {"help",no_argument,NULL,'h'},
66 {NULL,0,NULL,0}
67 };
68
69 if( opt==NULL )
70 {
71 printf("opt init failure!\n");
72 return -1;
73 }
/*参数解析:自己指定服务器ip和端口以及串口参数等,串口参数除设备以外,其他为可选*/
75 while( (ch=getopt_long(argc,argv,"i:P:D:b::d::s::p::h",opts,NULL))!=-1 )
76 {
77 switch(ch)
78 {
79 case 'i':
80 server_ip=optarg;
81 break;
82 case 'P':
83 Port=atoi(optarg);
84 break;
85 case 'D':
86 strncpy(opt->path,optarg,strlen(optarg));
87 break;
88 case 'b':
89 opt->baudrate=atol(optarg);
90 break;
91 case 'd':
92 opt->databit=atoi(optarg);
93 break;
94 case 's':
95 opt->stopbit=atoi(optarg);
96 break;
97 case 'p':
98 opt->parity=optarg[0];
99 break;
100 case 'h':
101 print_help(argv[0]);
102 return 0;
103 }
104 }
105
106 if( !server_ip || !Port || opt->path[0]==0 )
107 {
108 print_help(argv[0]);
109 return 0;
110 }
/*打开串口*/
112 if( USART_Open(opt)<0 )
113 {
114 printf("USART_Open failure!\n");
115 return 0;
116 }
117 printf("USART_Open ok!\n");
/*连接服务器*/
120 connfd=socket_connect(server_ip,Port);/*此函数自己封装*/
121 if( connfd<0 )
122 {
123 printf("connect to server failure!\n");
124 return -1;
125 }
131
132 while(1)
133
134 {
135 memset(data_buf,0,sizeof(data_buf));
136
137 printf("Input data:\n");
138 fgets(data_buf,64,stdin);
139
140 if( USART_Send(opt,data_buf,sizeof(data_buf))<0 )/*向串口发送数据*/
141 {
142 printf("USART_Send failure!\n");
143 break;
144 }
145 printf("USART_Send ok!\n");
148 rv= USART_Read(opt,rbuf,sizeof(rbuf));/*将串口数据读到rbuf中*/
149 if( rv<0 )
150 {
151 printf("USART_Send failure!\n");
152 break;
153
154 }
155 else if( rv==0 )
156 {
157 printf(" USART_Read timeout!\n");
158 break;
159
160 }
161
162 printf("USART_Read ok!\n");
163
164 if( write(connfd,rbuf,sizeof(rbuf))<0 )/*将rbuf中的数据发送给服务器*/
165 {
166 printf("write data failure!\n");
167 break;
168 }
169
170 printf("write data to server ok!\n");
171 }
172 close(connfd);
173 USART_Close(opt);
174 return 0;
175 }
服务器端的代码没什么特别的,就不贴了。
这是串口封装的代码:(https://github.com/hero-wangjiayang/code/tree/master/comport)
有问题欢迎指正!!!!