通過socket實現接收和傳送圖片檔案
阿新 • • 發佈:2018-12-06
今天採用udp協議實現接收和傳送圖片檔案,圖片格式是bmp。
udp提供面向事務的簡單不可靠資訊傳送服務,具有較好的實時性,它是一種無連線的傳輸層協議,工作效率比TCP高。
udp客戶端程式設計一般步驟:
1 、建立socket套接字
2 、配置ip port 協議簇
3 、sendto()傳送資訊
4 、close()關閉套接字
udp服務端程式設計一般步驟:
1、 建立socket套接字
2 、配置ip port 協議簇
3 、setsockopt()取消埠繫結限制(可選)
4 、bind()繫結ip port
5 、recvfrom()接收資訊
6 、close()關閉套接字
標頭檔案:
#ifndef _HEAD_H #define _HEAD_H #include <stdio.h> #include <sys/types.h> //socket所需標頭檔案 #include <sys/socket.h> #include <sys/socket.h> //ip 地址轉換所需標頭檔案 #include <netinet/in.h> #include <arpa/inet.h> //htonl htons 所需的標頭檔案 #include <string.h> //memset 所需標頭檔案 #include <unistd.h> //write read 所需標頭檔案 #include <stdlib.h> //malloc 所需標頭檔案 #include <sys/stat.h> //open 所需標頭檔案 #include <fcntl.h> #endif
客戶端:
#include "head.h" int main(int argc,char *argv[]) { if(argc<3) { //如 ./client 192.168.8.62 8888 /mnt/hgfs/Vms/a.bmp printf("傳參少了,你應該輸入 ./main ip port bmp\n"); return -1; } int client_fd; struct sockaddr_in dest_addr; //建立套接字 client_fd = socket(AF_INET,SOCK_DGRAM,0); //UDP if(client_fd == -1) { printf("create endpoint failed\n"); return -1; } //配置引數 dest_addr.sin_family = AF_INET; dest_addr.sin_addr.s_addr = inet_addr(argv[1]); dest_addr.sin_port = htons(atoi(argv[2])); int dest_len=sizeof(dest_addr); //傳送資訊 while(1) { int ret; int bmp_fd; int bmp_size; char *buf; //定點陣圖片 bmp_fd=open(argv[3],O_RDWR); if(bmp_fd==-1) { perror("open bmp failed!\n"); return -1; } //將讀寫位置移到檔案尾 bmp_size=lseek(bmp_fd,0,SEEK_END); //printf("bmp_size is:%d\n",bmp_size); //為bmp_size申請堆空間 buf=malloc(bmp_size); //將檔案指標偏移到開頭 lseek(bmp_fd,0,SEEK_SET); //將圖片大小讀出,放在buf中 read(bmp_fd,buf,bmp_size); //printf("bmp_size is:%d\n",bmp_size); //傳送圖片大小 ret=sendto(client_fd,buf,bmp_size,0,(struct sockaddr *)&dest_addr,dest_len); printf("ret is:%d\n",ret); if(ret == -1) { perror("Sendto "); return -1; } else break; close(bmp_fd); } //記得關閉套接字 close(client_fd); return 0; }
服務端:
#include "head.h"
int main(int argc,char*argv[])
{
if(argc<3)
{
//如 ./server 192.168.8.62 8888
printf("傳參少了,你應該輸入 ./main ip port\n");
return -1;
}
int server_id;
int bind_id;
struct sockaddr_in server_addr,from_addr;
//建立套接字
server_id=socket(AF_INET,SOCK_DGRAM,0);
if(server_id == -1)
{
perror("Create server_id failure");
return -1;
}
//配置引數
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr(argv[1]); //ip
server_addr.sin_port = htons(atoi(argv[2])); //port
int len=sizeof(struct sockaddr_in);
//取消埠繫結限制
int opt = 1;
if(setsockopt(server_id, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0)
{
perror("setsockopt error");
}
//繫結
bind_id=bind(server_id,(struct sockaddr *)&server_addr,len);
if(bind_id == -1)
{
perror("Create bind_id failure");
return -1;
}else
printf("Bind Success\n");
//接收資訊
int from_len=sizeof(from_addr);
int bmp_fd;
int ret;
char buf[10000];
bmp_fd=open("/home/gec/test.bmp",O_CREAT|O_RDWR|O_TRUNC);
if(bmp_fd==-1)
{
printf("create bmp failed!\n");
return -1;
}
ret=recvfrom(server_id,buf,10000,0,NULL,&from_len);
printf("ret is:%d\n",ret);
write(bmp_fd,buf,ret);
close(bmp_fd);
//關閉套接字
close(server_id);
return 0;
}