最近看到很多網友寫的socket程序,試驗了幾個,發送"Hello,world"時都沒有問題,但在傳輸較大文件,比如一個200M的文件時,都不能成功,即使成功了,server端也存在保存的問題, 有的是亂碼,也有文件大小不對的情況,這兩天工作不忙,我也草草寫了一些代碼,實現了可以傳輸任意格式任意大小的文件,幾位同事幫我一起做了測試,傳送幾百M的文件速度還是很快的,而且也沒有丟數據的問題。 代碼原理很簡單,所以也沒有做注釋,大家可以把代碼copy下來,自己把玩一下。現在我跟同事之間傳送datasheet,都在使用我的程序, 其實我也是個入行不深的人,代碼並沒有經過優化,很多printf() 是多余的,也有的地方寫的很麻煩。希望大家給以批評,給以幫助。
由於 網絡接口MTU的限制(一般mtu為1500),大些的文件只能分多次發送,這樣就有幾個問題:分幾次發送?一次發送多大? 保存端的怎麼保存?
我的辦法是:通過定義一個shouldoplen,來說明一次操作需要操作的長度,如果要發送的文件較小(跟buf相比),shouldoplen 就是讀取的文件大小,如果文件較大,需要多次發送,那麼shouldoplen 就是buf 的長度,通過多次讀取,發送, 直到發送出去的總長度oplencount 等於文件的大小,這時一個文件就算完整發送成功了。
編譯時:
gcc socket_server.c -lpthread -o server
gcc socket_client.c -o client
使用時:
在一端打開server
#./server
令一端使用client
#./client ./han/docunt/Linux_dd.pdf Linux_dd.pdf
這樣就把./han/docunt/Linux_dd.pdf 這就文件 發送server端,保存名為Linux_dd.pdf
當然,前提是在sock_client.c 中的把目的IP改為你要連接的目的IP。
***********************這是data.h****************
#ifndef DATA_H
#define DATA_H
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<fcntl.h>
#include<signal.h>
#include<pthread.h>
#include<sys/socket.h>
#include<errno.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include "data.h"
typedef unsigned int uint;
struct data{
char filename[30]; //要發送的文件名(可含路徑)
char filesavename[30]; //要保存的文件名(可含路徑)
uint filelen; //文件從字節數
uint shouldoplen; //一次要操作的字節數
uint oplencount; // 操作的字節總數
char filebuf[1300]; //由於mtu為1500,在不改動mtu的情況下,1300沒有問題。
};
struct data_return {
int writelen; //server端保存文件時,一次寫的長度
int writelencount; //寫的總數
int recvlen; //一次接受到的長度
};
#endif