python socket 网络编程 ,服务器端发的文件大小跟客户端接受打文件大小不一样?? 这是什么原因?

python socket 网络编程 ,服务器端发的文件大小跟客户端接受打文件大小不一样?? 这是什么原因?,第1张

很简单,你说让服务端发1024大小他就发1024大小吗,不一定tcp协议他会把内容先丢缓存再缓存拿,假设你让服务器发1024大小他有时候会分好几次发,你只要实时读取客户端接收文件大小就好了,和服务端发过来文件大小进行比较然后考虑后面要不要继续接收

服务器(Server)

[java] view plaincopy

package comsocketsample;

import javaioBufferedInputStream;

import javaioDataInputStream;

import javaioDataOutputStream;

import javaioFile;

import javaioFileInputStream;

import javanetServerSocket;

import javanetSocket;

public class ServerTest {

int port = 8821;

void start() {

Socket s = null;

try {

ServerSocket ss = new ServerSocket(port);

while (true) {

// 选择进行传输的文件

String filePath = "D:\\librar";

File fi = new File(filePath);

Systemoutprintln("文件长度:" + (int) filength());

// public Socket accept() throws

// IOException侦听并接受到此套接字的连接。此方法在进行连接之前一直阻塞。

s = ssaccept();

Systemoutprintln("建立socket链接");

DataInputStream dis = new DataInputStream(

new BufferedInputStream(sgetInputStream()));

disreadByte();

DataInputStream fis = new DataInputStream(

new BufferedInputStream(new FileInputStream(filePath)));

DataOutputStream ps = new DataOutputStream(sgetOutputStream());

// 将文件名及长度传给客户端。这里要真正适用所有平台,例如中文名的处理,还需要加工,具体可以参见Think In Java

// 4th里有现成的代码。

pswriteUTF(figetName());

psflush();

pswriteLong((long) filength());

psflush();

int bufferSize = 8192;

byte[] buf = new byte[bufferSize];

while (true) {

int read = 0;

if (fis != null) {

read = fisread(buf);

// 从包含的输入流中读取一定数量的字节,并将它们存储到缓冲区数组 b

// 中。以整数形式返回实际读取的字节数。在输入数据可用、检测到文件末尾 (end of file)

// 或抛出异常之前,此方法将一直阻塞。

}

if (read == -1) {

break;

}

pswrite(buf, 0, read);

}

psflush();

// 注意关闭socket链接哦,不然客户端会等待server的数据过来,

// 直到socket超时,导致数据不完整。

fisclose();

sclose();

Systemoutprintln("文件传输完成");

}

} catch (Exception e) {

eprintStackTrace();

}

}

public static void main(String arg[]) {

new ServerTest()start();

}

}

客户端工具(SocketTool)

[java] view plaincopy

package comsocketsample;

import javaioBufferedInputStream;

import javaioDataInputStream;

import javaioDataOutputStream;

import javanetSocket;

public class ClientSocket {

private String ip;

private int port;

private Socket socket = null;

DataOutputStream out = null;

DataInputStream getMessageStream = null;

public ClientSocket(String ip, int port) {

thisip = ip;

thisport = port;

}

/ /

/

创建socket连接

@throws Exception

exception

/

public void CreateConnection() throws Exception {

try {

socket = new Socket(ip, port);

} catch (Exception e) {

eprintStackTrace();

if (socket != null)

socketclose();

throw e;

} finally {

}

}

public void sendMessage(String sendMessage) throws Exception {

try {

out = new DataOutputStream(socketgetOutputStream());

if (sendMessageequals("Windows")) {

outwriteByte(0x1);

outflush();

return;

}

if (sendMessageequals("Unix")) {

outwriteByte(0x2);

outflush();

return;

}

if (sendMessageequals("Linux")) {

outwriteByte(0x3);

outflush();

} else {

outwriteUTF(sendMessage);

outflush();

}

} catch (Exception e) {

eprintStackTrace();

if (out != null)

outclose();

throw e;

} finally {

}

}

public DataInputStream getMessageStream() throws Exception {

try {

getMessageStream = new DataInputStream(new BufferedInputStream(

socketgetInputStream()));

return getMessageStream;

} catch (Exception e) {

eprintStackTrace();

if (getMessageStream != null)

getMessageStreamclose();

throw e;

} finally {

}

}

public void shutDownConnection() {

try {

if (out != null)

outclose();

if (getMessageStream != null)

getMessageStreamclose();

if (socket != null)

socketclose();

} catch (Exception e) {

}

}

}

客户端(Client)

[java] view plaincopy

package comsocketsample;

import javaioBufferedOutputStream;

import javaioDataInputStream;

import javaioDataOutputStream;

import javaioFileOutputStream;

public class ClientTest {

private ClientSocket cs = null;

private String ip = "localhost";// 设置成服务器IP

private int port = 8821;

private String sendMessage = "Windows";

public ClientTest() {

try {

if (createConnection()) {

sendMessage();

getMessage();

}

} catch (Exception ex) {

exprintStackTrace();

}

}

private boolean createConnection() {

cs = new ClientSocket(ip, port);

try {

csCreateConnection();

Systemoutprint("连接服务器成功!" + "\n");

return true;

} catch (Exception e) {

Systemoutprint("连接服务器失败!" + "\n");

return false;

}

}

private void sendMessage() {

if (cs == null)

return;

try {

cssendMessage(sendMessage);

} catch (Exception e) {

Systemoutprint("发送消息失败!" + "\n");

}

}

private void getMessage() {

if (cs == null)

return;

DataInputStream inputStream = null;

try {

inputStream = csgetMessageStream();

} catch (Exception e) {

Systemoutprint("接收消息缓存错误\n");

return;

}

try {

// 本地保存路径,文件名会自动从服务器端继承而来。

String savePath = "E:\\";

int bufferSize = 8192;

byte[] buf = new byte[bufferSize];

int passedlen = 0;

long len = 0;

savePath += inputStreamreadUTF();

DataOutputStream fileOut = new DataOutputStream(

new BufferedOutputStream(new FileOutputStream(savePath)));

len = inputStreamreadLong();

Systemoutprintln("文件的长度为:" + len + "\n");

Systemoutprintln("开始接收文件!" + "\n");

while (true) {

int read = 0;

if (inputStream != null) {

read = inputStreamread(buf);

}

passedlen += read;

if (read == -1) {

break;

}

// 下面进度条本为图形界面的prograssBar做的,这里如果是打文件,可能会重复打印出一些相同的百分比

Systemoutprintln("文件接收了" + (passedlen 100 / len) + "%\n");

fileOutwrite(buf, 0, read);

}

Systemoutprintln("接收完成,文件存为" + savePath + "\n");

fileOutclose();

} catch (Exception e) {

Systemoutprintln("接收消息错误" + "\n");

return;

}

}

public static void main(String arg[]) {

new ClientTest()getMessage();

}

}

测试是成功的,在DOS命令行下编译~~~

1、可以在client端登入时write(发送)帐号和密码给server端,当server端接受到内容时判断是否是你预设的帐号密码,是则允许下载,否则关闭其socket。

2、是要客户端看到进度条? 这样就要要求在下载文件时server端要先发这个文件的大小给client端,client端就可以通过这个大小和接受到的字节数比较后打印进度条(printf("#");)

文件大小可用int stat(const char restrict path, struct stat restrict buf);函数获取。

那两java是在一个包里的,其中一个是main函数的。也就是说,mian的java启动了另一个java文件。所以你只有选择那整个包,run as java application就是运行服务器了

调用程序时把要传输的文件名作为第三个参数。

Clientexe IPAddress Port FileName

然后在程序中判断argv[3]为文件名(如果想支持多文件发送,则argv4以后的也可以判断为要发送的文件,类似Clientexe IPAddress Port FileName1 FileName2)。

至于读写文件,其实很简单,用fopen或fstream均可。

以下是fopen的例子: (为了保持格式用了一个特殊的空格,如果要编译自己批量替换下)

int main(int argc, char argv[])

{

��if (argc < 4)

��{

����ShowUage();

��}

��//初始化通讯的省略。

��

��for (size_t i = 3; i< argc; ++i )

��{

����char fileName = argv[i];

����if (FileExist(fileName))

����{

������SendFileName(theSocket, fileName);

������SendFileSize(theSocket, fileName);

������SendFileContent(theSocket, fileName);

����}

��}

}

bool FileExist(char fileName)

{

��FILE fp = fopen(fileName, "rb");

��if (fp !=NULL)

��{

����fclose(fp);

����return TRUE;

��}

��return FALSE;

}

SendFileName(theSocket, char fileName)

{

��size_t length = strlen(fileName);

��send( theSocket, &length, 4, 0 );

��send( theSocket, fileName, length, 0 );

}

SendFileSize(theSocket, char fileName)

{

��FILE fp = fopen(fileName, "rb");

��fseek(fp, 0, SEEK_END);

��size_t fileSize = ftell(fp);

��fclose(fp);

��send( theSocket, &fileSize, 4, 0 );

}

SendFile(theSocket, char fileName)

{

��FILE fp = fopen(fileName, "rb");

��unsigned char buffer[512];

��while (!feof(fp))

��{

����size_t size�= fread(buffer, 1, sizeof(buffer), fp);

����send( theSocket, &buffer, size, 0 );

��}

}

对应接收端要另外实现RecvFileName,RecvFileSize,RecvFile这三个接口。

DABAN RP主题是一个优秀的主题,极致后台体验,无插件,集成会员系统
网站模板库 » python socket 网络编程 ,服务器端发的文件大小跟客户端接受打文件大小不一样?? 这是什么原因?

0条评论

发表评论

提供最优质的资源集合

立即查看 了解详情