Vaya a la comunicación de red de idiomas --- tcp cargue archivos grandes (el problema del paquete fijo debe resolverse con elegancia)

Lado del servidor:

paquete de 

importación principal ( 
	"bufio" 
	"codificación / binario" 
	"fmt" 
	"net" 
	"os" 
	"inseguro" 
) 

func SHandleError (error de error, cuando cadena) { 
	if err! = nil { 
		fmt.Println ("服务 端 异常 退出, Err = ", err, when) 
		os.Exit (1) 
	} 
} 

func BytesToInt64 (buf [] byte) int64 { 
	return int64 (binary.BigEndian.Uint64 (buf)) 
} 

func main () { 
	// 建立 tcp 监听
	oyente, e: = net.Listen ("tcp", ": 8080") 
	SHandleError (e, "net.Listen") 
	diferir func () { 
		listener.Close () 
		fmt.Println ("服务 端 正常 退出") 
	} () 
 
	// Acepte la solicitud del cliente, establezca una línea dedicada de sesión Conn
	conn, e: = oyente. Aceptar () 
	SHandleError (e, "listener.Accept") 
	difiere func () { 
		conn.Close () 
		fmt.Printf ("El enlace con% v se ha desconectado \ n", conn.RemoteAddr ()) 
	} () 

	dstFile, e: = os.OpenFile (`meinv1.mp4`, os.O_CREATE | os.O_WRONLY | os.O_TRUNC, 0666) 
	escritor: = bufio.NewWriter (dstFile) 
	aplazar dstFile.Close () 
	buffer: = make ([] byte, 100) 
	total: = 0 

	// Acepte el tamaño del archivo a enviar desde el cliente 
	buffer2: = make ([] byte, 10) 
	m, e: = conn.Read (buffer2) 
	/ / size: = string (buffer2 [: m]) 
	//fmt.Printf("%s\n",size) 
	// i, _: = strconv.Atoi (size) 

	// [] byte convertido a int64 
	i: = BytesToInt64 (buffer2 [: m]) 
	fmt.Printf ("% d,% T \ n", i, i)
	// int64 convertido a int 
	j: = * (* int) (inseguro.Pointer (& i))
	fmt.Printf ("% d,% T \ n", j, j) 

	para { 
		// Aceptar el archivo cargado por el cliente 
		n, e: = conn.Read (buffer) 
		SHandleError (e, "conn.Read") 
		total + = n 

		// Escribir en el servidor local de 
		escritor de escritor. Escribir (buffer [: n]) 
		escritor . Enjuagar () 

		fmt.Printf ("Escrito exitosamente% d bytes, total% d bytes \ n", n , total) 

		// Si el número total real de bytes recibidos es igual al número de bytes a transmitir por el cliente, significa que la transferencia se completa 
		si total == j { 
			fmt.Println ("Archivo aceptado con éxito, total", total, "bytes ") 
			// Responde que el cliente ha recibido el archivo 
			conn.Write ([] byte (" El archivo se ha aceptado correctamente ")) 
			break 
		} 
	} 
}

lado del cliente:



importación principal del paquete ( 
	codificación "bufio" 
	/ binario " 
	" fmt " 
	" io " 
	" net " 
	" os " 
	" time " 
) 

/ * 
· 实现 tcp 文件 上传 功能
* / 

func CHandleError2 (error err, cuando cadena) { 
	if err ! = nil { 
		fmt.Println ("客户 端 异常 退出 : err =", err, when) 
		os.Exit (1) 
	} 
} 
func Int64ToBytes (i int64) [] byte { 
	var buf = make ([] byte, 8 ) 
	binary.BigEndian.PutUint64 (buf, uint64 (i)) 
	return buf 
} 
func main () { 
	conn, e: = net.Dial ("tcp", "127.0.0.1:8080") 
	CHandleError2 (e, "net. Marcar") 

	diferir func () { 
		conn.Close () 
		fmt.Println ("El cliente sale normalmente")
	} () 

	// Obtenga el tamaño del archivo de destino y páselo al servidor 
	fileInfo, _: = os.Stat (`perfect.mp4`) 
	tamaño: = fileInfo.Size () 
	bytes: = Int64ToBytes (size) 
	conn.Write (bytes ) 

	// Resuelva temporalmente el problema del paquete fijo a través de la suspensión del cliente 200 milisegundos, y también se puede resolver mediante la reconexión tcp. Más tarde, use (encabezado del paquete + datos) para encapsular el paquete de datos. 
	Time.Sleep (time.Millisecond * 200) 

	buffer: = make ([] byte, 100) 
	srcFile, _: = os.Open (`perfect.mp4`) 
	reader: = bufio.NewReader (srcFile) 
	total: = 0 
	for { 
		n, err: = reader.Read (buffer) 
		fmt .Println (n, err) 
		if err == io.EOF { 
			fmt.Println ("Archivo enviado completado") 
			fmt.Println (total) 
			break 
		} else { 
			_, e = conn.Write (buffer [: n])
			total + = n 
			CHandleError2 (e, "conn.Write") 
		}
	} 

	n, e: = conn.Read (buffer) 
	CHandleError2 (e, "conn.Read") 
	replyMsg: = buffer [: n] 
	fmt.Println ("服务 端 :", string (replyMsg)) 
}

  

Supongo que te gusta

Origin www.cnblogs.com/yunweiqiang/p/12735452.html
Recomendado
Clasificación