嵌入式与计算机网络编程,Lab8 : 网络LED矩阵显示器 - 嵌入式与计算机网络

前言

本次实验延续上次实验的环境,使用MAX7219驱动8x8点阵。上位机使用Ubuntu 14.04,下位机使用Raspberry pi 2。

使用的还是上次实验编译好的非阻塞式写入点阵支持内核模块。

这次的实验跟计网实验好像啊好像啊。

控制点阵显示字符

通过write函数向device写入数据即可。

#include

#include

#include

#include

#include

int Matrix;

#define ALLCHAR "0123456789abcdefghijklmnopqrstuvwxyz"

int main(){

Matrix = open("/dev/matrix", O_WRONLY);

if (Matrix < 0){

fprintf(stderr, "Cound not open matrix device");

exit(1);

}

write(Matrix, ALLCHAR, strlen(ALLCHAR));

return 0;

}

编写网络程序接受TCP请求

使用linux下的socket编程,接受外部TCP请求,并将其发送来的所有数据写入matrix设备即可实现显示功能。

ba2addedcd71

Socket流程图 | 图自[Linux的SOCKET编程详解](http://blog.csdn.net/hguisu/article/details/7445768)

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

int Matrix;

int server;

#define PORT 8080

#define ADDR "0.0.0.0"

#define QUEUE 20

#define BUFF_SIZE 2048

int main(){

// 打开matrix

Matrix = open("/dev/matrix", O_WRONLY);

if (Matrix < 0){

fprintf(stderr, "Cound not open matrix device\n");

exit(1);

}

// 建立服务器

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);

// 绑定ip以及端口

if (bind(server, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) == -1){

fprintf(stderr, "Count not bind %s:%d\n", ADDR, PORT);

exit(1);

}

if (listen(server, QUEUE) == -1){

fprintf(stderr, "Listen error\n");

exit(1);

}

printf("Server running at %s:%d\n", ADDR, PORT);

while (1){

struct sockaddr_in clientAddr;

socklen_t length = sizeof(clientAddr);

// 对连入的连接进行处理

int conn = accept(server, (struct sockaddr*)&clientAddr, &length);

if (conn < 0){

fprintf(stderr, "Connect error");

exit(1);

}

printf("A new connection from %s:%d\n", inet_ntoa(clientAddr.sin_addr), clientAddr.sin_port);

// 处理连接发送过来的字符

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;

}

// 将接收到的所有字符发送给matrix进行显示

write(Matrix, receiveBuf, count);

}

}

close(server);

return 0;

}

ba2addedcd71

树莓派本地连入

ba2addedcd71

上位机远程连入

使用线程处理多个连接

上一节的程序使用的是阻塞式的处理连接,这将导致服务器每次accept了一个连接之后,无法再处理其余连接。

而这种情况的处理方式有很多。可以使用一个线程对应一个socket fd的方式进行阻塞式监听。也可以使用IO多路复用,如select、poll、epoll,在单线程的环境下进行高效的网络IO操作。

使用线程的方式对于阻塞式程序的改动较小,基本上逻辑还是一致的。

…………

void* serverRecv(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;

}

write(Matrix, receiveBuf, count);

}

pthread_exit(NULL);

return NULL;

}

…………

int main(){

…………

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);

int result;

if (conn < 0){

fprintf(stderr, "Connect error");

exit(1);

}

printf("A new connection from %s:%d\n", inet_ntoa(clientAddr.sin_addr), clientAddr.sin_port);

result = pthread_create(&thread, NULL, serverRecv, &conn);

if (result < 0){

printf("Create thread error\n");

exit(1);

}

}

…………

}

在这个版本中,主程序只负责接受连接,而接受到的连接交由子线程进行监听处理。

参考资料

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值