Assignment 108: Lab 8:网络LED矩阵显示器
这个实验的目的是掌握Linux网络程序和多线程程序的编写,实现一个网络访问的LED矩阵显 示器。
实验目的
实验器材
硬件
以下为自备(可选)器材:
软件
实验步骤
1. 设计外部设备方案,画连线示意图;
2. 在面包板上连线,完成外部电路;
这次实验的连线图和上次一致:
具体连线拍照效果可见后文的结果展示。
3. 编写Linux应用程序,能通过第七次实验的设备驱动程序控制LED矩阵显示字符串,每个字符停留500ms;
启动led显示屏的方法和上次一致,只是上次在终端直接使用echo输出,这次试用write函数。运行之前需要安装内核模块。并且使用root模式。
#include <string.h> |
#include <unistd.h> |
#include <sys/types.h> |
#include <sys/stat.h> |
#include <fcntl.h> |
int main(){ |
int matrix; |
char str[10]=”123456”; |
matrix = open("/dev/matrix", O_WRONLY); |
if (matrix < 0){ //open failed |
return(-1); |
} |
write(Matrix, str, strlen(str)); |
return 0; |
} |
4. 编写Linux应用程序,能通过TCP接受一个连接,将发来的文字在LED矩阵上流动显示出来;
编写socket程序,和之前计算机网络课程做的实验类似。由于需要支持多个终端同时登陆,这里需要使用多线程,来防止一个终端连接后recv命令的阻塞。函数中首先开始监听是否有客户端连接,一旦有客户端连入,就新开启一个线程用于监听输入。代码如下:
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#include <unistd.h> |
#include <sys/types.h> |
#include <sys/stat.h> |
#include <fcntl.h> |
#include <netinet/in.h> |
#include <arpa/inet.h> |
#include <sys/socket.h> |
int Matrix; |
int server; |
#define PORT 8080 |
#define ADDR "0.0.0.0" |
#define QUEUE 20 |
#define BUFF_SIZE 2048 |
|
void* onServerRecv(void* data){ |
int conn = *(int*)data; |
while (1){ |
char receiveBuf[BUFF_SIZE]; |
int count; |
memset(receiveBuf, 0, sizeof(receiveBuf)); |
count = recv(conn, receiveBuf, sizeof(receiveBuf), 0); |
if (count == 0){ |
close(conn); |
break; |
} |
printf("Receiver: %s",receiveBuf); |
write(Matrix, receiveBuf, count); |
} |
pthread_exit(NULL); |
return NULL; |
} |
|
int main(){ |
|
// open matrix |
Matrix = open("/dev/matrix", O_WRONLY); |
if (Matrix < 0){ |
printf("Open matrix failed.\n"); |
exit(1); |
} |
// start server |
int server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); |
struct sockaddr_in serverAddr; |
serverAddr.sin_family = AF_INET; |
serverAddr.sin_addr.s_addr = inet_addr(ADDR); |
serverAddr.sin_port = htons(PORT); |
// bind |
if (bind(server, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) == -1){ |
printf("Bind failed %s:%d\n", ADDR, PORT); |
exit(1); |
if (listen(server, QUEUE) == -1){ |
printf("Listen failed.\n"); |
exit(1); |
} |
printf("Server running at %s:%d\n", ADDR, PORT); |
while (1){ |
pthread_t thread; |
struct sockaddr_in clientAddr; |
socklen_t length = sizeof(clientAddr); |
int conn = accept(server, (struct sockaddr*)&clientAddr, &length); |
if (conn < 0){ |
printf("Connect failed."); |
exit(1); |
} |
printf("A new connection from %s:%d\n", inet_ntoa(clientAddr.sin_addr), clientAddr.sin_port); |
int temp = pthread_create(&thread, NULL, onServerRecv, &conn); |
if (temp < 0){ |
printf("Create thread failed.\n"); |
exit(1); |
} |
} |
close(server); |
return 0; |
} |
由于使用了线程库,编译的时候需要加上库选项:
gcc myserver.c -lpthread |
5. 用telnet连接Linux板卡,发送字符串来显示。
首先查看telnet是否可以正常执行:
由于放在一个路由器下,连接比较简单。连接成功,发送消息后,可以在led显示屏上看到输出(这之前需要如lab7一样安装内核模块):
可以看到连续显示了1234,实验成功。