今天采用udp协议实现接收和发送图片文件,图片格式是bmp。
udp提供面向事务的简单不可靠信息传送服务,具有较好的实时性,它是一种无连接的传输层协议,工作效率比TCP高。
udp客户端编程一般步骤:
1 、创建socket套接字
2 、配置ip port 协议簇
3 、sendto()发送信息
4 、close()关闭套接字
udp服务端编程一般步骤:
1、 创建socket套接字
2 、配置ip port 协议簇
扫描二维码关注公众号,回复:
4392938 查看本文章
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;
}