1. 程式人生 > >通過socket實現接收和傳送圖片檔案

通過socket實現接收和傳送圖片檔案

今天採用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;
}

​