1.要求: 在Ubuntu上用命令控制开发板图片显示
full命令--》全屏显示
half命令--》1/2显示
double命令 两倍显示
2. server.c
#include <sys/socket.h>
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <error.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/sendfile.h>
#define SPORT 8888 // >1024
int main(int argc,char **argv)
{
int sfd, newsfd;
int fd;
int fsize;
struct sockaddr_in saddr4;
struct stat stat;
char sbuf[50];
// 创建套接字(IPV4 TCP)
sfd = socket(AF_INET, SOCK_STREAM, 0);
// 设置套接字IP可复用
const int bReuseaddr = 1;
setsockopt(sfd,SOL_SOCKET ,SO_REUSEADDR,(const void*)&bReuseaddr,sizeof(bReuseaddr));
// 设置套接字发送缓冲区为32k (默认为8k)
const int nSendBuf = 32 * 1024;//设置为32K
setsockopt(sfd,SOL_SOCKET,SO_SNDBUF,(const void*)&nSendBuf,sizeof(int));
// 绑定服务端地址
memset(&saddr4, 0, sizeof(saddr4));
saddr4.sin_family = AF_INET;
saddr4.sin_port = htons(SPORT);
saddr4.sin_addr.s_addr = inet_addr ("192.168.0.101");
if (0 < bind(sfd, (struct sockaddr *)&saddr4, sizeof(saddr4))) {
perror("bind err");
return -1;
}
// 监听
listen(sfd, 5);
// 打开文件
fd = open(argv[1], O_RDONLY);
if (fd == -1) {
printf("open %s err\n", argv[1]);
perror("");
return -1;
}
// 获取文件大小
fstat(fd, &stat);
fsize = stat.st_size;
printf("fsize = %d\n", fsize);
// 接收(阻塞接口, 等待连接后才可监听)
newsfd = accept(sfd, NULL, NULL);
printf("accept ok\n");
printf("input enter send filesize\n");
getchar();
// 告诉客户端即将发送的文件有多大
bzero(sbuf, sizeof(sbuf));
sprintf(sbuf, "%d", fsize);
send(newsfd, sbuf, strlen(sbuf), 0);
printf("input enter send file\n");
getchar();
// 发送文件
if (0 > sendfile(newsfd, fd, 0, fsize)){
perror("sendfile err\n");
return -1;
}
printf("enter cmd\n");
// 发送命令
while(1) {
bzero(sbuf, sizeof(sbuf));
fgets(sbuf, sizeof(sbuf), stdin);
send(newsfd, sbuf, strlen(sbuf), 0);
}
return 0;
}
3.client.c
#include <sys/socket.h>
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <error.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include "../include/pic/pic.h"
#include "../include/pic/bmp.h"
#include "../include/pic/fb.h"
#include "../include/conf.h"
#define CPORT 7777 // >1024
#define SPORT 8888 // >1024
#define RecvBufSize 32 * 1024
void show_pic_(int cfd, const char *pic_path)
{
int ret;
char cbuf[50]; // 接收命令的buf
bitmap_t bitmap;
bitmap_t zoombm;
fbdev_t fbdev;
int i, j=0;
memset(&bitmap, 0, sizeof(bitmap));
memset(&fbdev, 0, sizeof(fbdev));
ret = open_fb_device("/dev/fb0", &fbdev);
//print_dev_info(&fbdev);
ret = get_bitmap_from_bmpfile(pic_path, &bitmap);
while (1) {
bzero(cbuf, sizeof(cbuf));
CUR;
ret = recv(cfd, cbuf, sizeof(cbuf), 0);
printf("ret = %d\n", ret);
printf("cbuf = %s\n", cbuf);
CUR;
fb_clear_screen(&fbdev, 0x000000);
if (!strncmp(cbuf, "full", 4)) {
CUR;
merge_bitmap_to_fbdev(&fbdev, 0, 0, &bitmap);
}
else if (!strncmp(cbuf, "half", 4)){
CUR;
memset(&zoombm, 0, sizeof(zoombm));
zoom(&bitmap, &zoombm, 0.5);
merge_bitmap_to_fbdev(&fbdev, 0, 0, &zoombm);
free_bitmap(&zoombm);
}
else if (!strncmp(cbuf, "double", 6)){
CUR;
memset(&zoombm, 0, sizeof(zoombm));
zoom(&bitmap, &zoombm, 2);
merge_bitmap_to_fbdev(&fbdev, 0, 0, &zoombm);
free_bitmap(&zoombm);
}
//free_bitmap(&bitmap);
//close_fb_dev(&fbdev);
}
}
int main(int argc,char **argv)
{
int cfd;
struct sockaddr_in caddr4; // 客户端进程地址
struct sockaddr_in saddr4; // 服务端进程地址
int fsize;
char tbuf[50];
char rbuf[RecvBufSize];
int newfile_fd;
int ret, cnt = 0;
// 创建套接字(IPV4 TCP)
cfd = socket(AF_INET, SOCK_STREAM, 0);
// 设置套接字IP可复用
const int bReuseaddr = 1;
setsockopt(cfd,SOL_SOCKET ,SO_REUSEADDR,(const void*)&bReuseaddr,sizeof(bReuseaddr));
// 设置套接字接收缓冲区为32k (默认为8k)
const int nRecvBuf = RecvBufSize; //设置为32K
setsockopt(cfd,SOL_SOCKET,SO_SNDBUF,(const void*)&nRecvBuf,sizeof(int));
// 客户端不用绑定。 因为调用connect时, 如果服务端套接字sockfd没有绑定到一个地址,系统会给sockfd绑定一个未使用的默认地址
// 连接客户端
saddr4.sin_family = AF_INET;
saddr4.sin_port = htons(SPORT);
saddr4.sin_addr.s_addr = inet_addr ("192.168.0.101");
if (-1 == connect(cfd, ((struct sockaddr *)&saddr4), sizeof(saddr4))){
perror("connect err");
return -1;
}
printf("connect serverIp 192.168.0.101 ok\n");
// 接收文件的大小信息
bzero(tbuf, sizeof(tbuf));
recv(cfd, tbuf, sizeof(tbuf), 0);
fsize = (int)strtoul(tbuf, NULL, 0);
printf("fsize = %d\n", fsize);
// 创建一个新文件来存取数据
newfile_fd = open("new.bmp", O_CREAT | O_RDWR);
if (newfile_fd == -1) {
perror("creat new.bmp err");
}
// 将文件截断为0
ftruncate(newfile_fd, 0);
int i;
// 接收文件
while(1) {
bzero(rbuf, sizeof(rbuf));
if (cnt < fsize)
ret = recv(cfd, rbuf, sizeof(rbuf), 0);
else {
printf("recved finish\n");
goto show_pic;
}
if (ret == 0) {
printf("disconnect\n");
return -1;
}
else if(ret < 0){
printf("recv err\n");
close(cfd);
close(newfile_fd);
return -1;
}
else { // 正常接收
printf("ret = %d\n", ret);
//printf("recved %s\n", rbuf);
if (0 > write(newfile_fd, rbuf, ret)){ // 接收到的数据写入文件
perror("write err");
return -1;
}
cnt += ret;
}
}
show_pic:
printf("show pic\n");
close(newfile_fd);
show_pic_(cfd, "new.bmp");
return 0;
}