python tcp接收图片(自定义协议)

我通过linux端传送图片到服务器端,由于tcp协议具有MTU的规定,所以一张照片会被分成多包传输。

下面是我的c和python代码,python为接收端,c为发送端,后续会进行优化。

C代码(client):
读取图片并传输

#include "tcpmqtt.h"

#include <sys/stat.h>
unsigned long get_file_size(const char *path)
{
	unsigned long filesize = -1;	
	struct stat statbuff;
	if(stat(path, &statbuff) < 0){
		return filesize;
	}else{
		filesize = statbuff.st_size;
	}
		return filesize;
}

int publish_picture(char *ip, int port, char* path)
{
    unsigned char image_head[] = {0x8f, 0x8d, 0x00, 0x00, 0x00, 0x00};
    char recvline[4096],sendline[4096];
    struct sockaddr_in servaddr;
	int sockfd, len;
    memset(&servaddr,0,sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(port);
    FILE *fp;
	int file_size = 0;
    //创建socket
    if( (sockfd = socket(AF_INET,SOCK_STREAM,0)) == -1) {
        printf(" create socket error: %s (errno :%d)\n",strerror(errno),errno);
        return -1;
    }

	file_size = get_file_size(path);
	printf("file size : %d \n", file_size);
	image_head[2] = ((file_size & 0xff000000)>>24);
	image_head[3] = ((file_size & 0xff0000) >> 16);
	image_head[4] = ((file_size & 0xff00) >> 8);
	image_head[5] = ((file_size & 0xff));


	if((fp = fopen(path, "rb")) == NULL)
	{
		printf("open picture failed\n");
		return -1;
	}
    
    if( inet_pton(AF_INET,ip, &servaddr.sin_addr) <=0 ) {
        printf("inet_pton error for %s\n", ip);
        return -1;
    }
    
    //连接
    if( connect(sockfd,(struct sockaddr*)&servaddr,sizeof(servaddr)) <0) {
        printf(" connect socket error: %s(errno :%d)\n",strerror(errno),errno);
        return -1;
    }
    
    if ( send(sockfd, image_head, sizeof(image_head), 0) <0) {
        printf("send msg error: %s(errno :%d)\n",strerror(errno),errno);
        return -1;
    }
   
	while(!feof(fp)){
		len = fread(sendline, 1, sizeof(sendline), fp);

		if(len != write(sockfd, sendline, len)){
			printf("write..\n");
			break;
		}
	}
	fclose(fp);
    close(sockfd);
}

python代码,接收图片并解析:

# -*- coding: utf-8 -*-
"""
Created on Mon Nov 25 10:54:58 2019

@author: admin
"""
from socket import *


def recv_cmd_head(socketid, headsize):
    recv_data = socketid.recv(headsize)
    recvlen = 0
    #print('recv len:', len(recv_data))
    
    if len(recv_data) != headsize:
        return 0
    
    if recv_data[0] == 143 and recv_data[1] == 141:
        print(recv_data[0], recv_data[1])
        recvlen = recv_data[2] * 16777216 + recv_data[3] * 65536 + \
                    recv_data[4] * 256 + recv_data[5]
        
    return recvlen



def recv_picture(socketid, size, path):
    #recv_data = 0
    count = 0
    #wb以二进制方式写文件,因为我们的tcp接收数据为二进制byte的类型
    file = open(path, 'wb')
    while True: 
        
        recv_data = socketid.recv(size)
        print(count, len(recv_data))
        if len(recv_data) != 0:
            count += len(recv_data)
            file.write(recv_data);
        else:
            file.close()
            break
    


if __name__ == '__main__':
    picpath = 'C:/Users/admin/Desktop/pycode/pictest.png'
    headsize = 6

    tcp_server_socket = socket(AF_INET, SOCK_STREAM)
    
    # 本地信息
    address = ('', 7788)
    
    tcp_server_socket.bind(address)
    tcp_server_socket.listen(128)
    client_socket, clientAddr = tcp_server_socket.accept()
    
    recv_len = recv_cmd_head(client_socket, headsize)
    
    print('应接收到的数据为:', recv_len)
    
    recv_picture(client_socket, recv_len, picpath)
    client_socket.close()


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值