⑴ 怎麼用java的socket進行文件傳輸誰能給個簡單的例子,包括發送端和接收端。
java中的網路信息傳輸方式是基於TCP協議或者UD協議P的,socket是基於TCP協議的
例子1
(1)客戶端程序:
import java.io.*;
import java.net.*;
public class Client
{ public static void main(String args[])
{ String s=null;
Socket mysocket;
DataInputStream in=null;
DataOutputStream out=null;
try{
mysocket=new Socket("localhost",4331);
in=new DataInputStream(mysocket.getInputStream());
out=new DataOutputStream(mysocket.getOutputStream());
out.writeUTF("你好!");//通過 out向"線路"寫入信息。
while(true)
{
s=in.readUTF();//通過使用in讀取伺服器放入"線路"里的信息。堵塞狀態,
//除非讀取到信息。
out.writeUTF(":"+Math.random());
System.out.println("客戶收到:"+s);
Thread.sleep(500);
}
}
catch(IOException e)
{ System.out.println("無法連接");
}
catch(InterruptedException e){}
}
}
(2)伺服器端程序:
import java.io.*;import java.net.*;
public class Server
{ public static void main(String args[])
{ ServerSocket server=null;
Socket you=null;String s=null;
DataOutputStream out=null;DataInputStream in=null;
try{ server=new ServerSocket(4331);}
catch(IOException e1){System.out.println("ERRO:"+e1);}
try{ you=server.accept();
in=new DataInputStream(you.getInputStream());
out=new DataOutputStream(you.getOutputStream());
while(true)
{
s=in.readUTF();// 通過使用in讀取客戶放入"線路"里的信息。堵塞狀態,
//除非讀取到信息。
out.writeUTF("你好:我是伺服器");//通過 out向"線路"寫入信息.
out.writeUTF("你說的數是:"+s);
System.out.println("伺服器收到:"+s);
Thread.sleep(500);
}
}
catch(IOException e)
{ System.out.println(""+e);
}
catch(InterruptedException e){}
}
}
例子(2)
(1) 客戶端
import java.net.*;import java.io.*;
import java.awt.*;import java.awt.event.*;
import java.applet.*;
public class Computer_client extends Applet implements Runnable,ActionListener
{ Button 計算;TextField 輸入三邊長度文本框,計算結果文本框;
Socket socket=null;
DataInputStream in=null; DataOutputStream out=null;
Thread thread;
public void init()
{ setLayout(new GridLayout(2,2));
Panel p1=new Panel(),p2=new Panel();
計算=new Button(" 計算");
輸入三邊長度文本框=new TextField(12);計算結果文本框=new TextField(12);
p1.add(new Label("輸入三角形三邊的長度,用逗號或空格分隔:"));
p1.add( 輸入三邊長度文本框);
p2.add(new Label("計算結果:"));p2.add(計算結果文本框);p2.add(計算);
計算.addActionListener(this);
add(p1);add(p2);
}
public void start()
{ try
{ //和小程序所駐留的伺服器建立套接字連接:
socket = new Socket(this.getCodeBase().getHost(), 4331);
in =new DataInputStream(socket.getInputStream());
out = new DataOutputStream(socket.getOutputStream());
}
catch (IOException e){}
if(thread == null)
{ thread = new Thread(this);
thread.start();
}
}
public void run()
{ String s=null;
while(true)
{ try{ s=in.readUTF();//堵塞狀態,除非讀取到信息。
計算結果文本框.setText(s);
}
catch(IOException e)
{ 計算結果文本框.setText("與伺服器已斷開");
break;
}
}
}
public void actionPerformed(ActionEvent e)
{ if(e.getSource()==計算)
{ String s=輸入三邊長度文本框.getText();
if(s!=null)
{ try { out.writeUTF(s);
}
catch(IOException e1){}
}
}
}
}
(2) 伺服器端
import java.io.*;import java.net.*;
import java.util.*;import java.sql.*;
public class Computer_server
{ public static void main(String args[])
{ ServerSocket server=null;Server_thread thread;
Socket you=null;
while(true)
{ try{ server=new ServerSocket(4331);
}
catch(IOException e1)
{ System.out.println("正在監聽"); //ServerSocket對象不能重復創建。
}
try{ you=server.accept();
System.out.println("客戶的地址:"+you.getInetAddress());
}
catch (IOException e)
{ System.out.println("正在等待客戶");
}
if(you!=null)
{ new Server_thread(you).start(); //為每個客戶啟動一個專門的線程。
}
else
{ continue;
}
}
}
}
class Server_thread extends Thread
{ Socket socket;Connection Con=null;Statement Stmt=null;
DataOutputStream out=null;DataInputStream in=null;int n=0;
String s=null;
Server_thread(Socket t)
{ socket=t;
try { in=new DataInputStream(socket.getInputStream());
out=new DataOutputStream(socket.getOutputStream());
}
catch (IOException e)
{}
}
public void run()
{ while(true)
{ double a[]=new double[3] ;int i=0;
try{ s=in.readUTF();堵塞狀態,除非讀取到信息。
StringTokenizer fenxi=new StringTokenizer(s," ,");
while(fenxi.hasMoreTokens())
{ String temp=fenxi.nextToken();
try{ a[i]=Double.valueOf(temp).doubleValue();i++;
}
catch(NumberFormatException e)
{ out.writeUTF("請輸入數字字元");
}
}
double p=(a[0]+a[1]+a[2])/2.0;
out.writeUTF(" "+Math.sqrt(p*(p-a[0])*(p-a[1])*(p-a[2])));
sleep(2);
}
catch(InterruptedException e){}
catch (IOException e)
{ System.out.println("客戶離開");
break;
}
}
}
}
這些例子都是Java2實用教程上的.
⑵ java socket 如何發送一個結構體消息,java中結構體是個什麼概念...
有一個socket 程序,一端是c++寫的socket 服務程序
另一端是Java寫客戶端程序,兩者之間需要通信。
c++/c接收和發送的都是結構體,而Java是直接發送的位元組流或者byte 數組。
解決方法:c++/c socket 在發送結構體的時候其實發送的也是位元組流。因為結構體本身也是內存中的一塊連續數據。問題就變成了如何把結構體手動轉成位元組的問題了
採用類似的報頭:
// packet head
typedef struct tagPacketHead{
long PacketID;
long PacketLen;
}PacketHead;此時套介面的讀寫方式為先讀報頭,在報頭中取出數據負載的長度,然後再讀相應位元組的數據。
包頭後面跟上包體,其中包體的長度,就是上面結構體中的PacketLen,Clinet首先接受包頭,因為包頭是兩邊約定好的,所以可以直接Receive一個定長的消息,也就是這個包頭的長度的消息,從包頭中取得包體的長度後,就可以再次Receive一個包體長度的消息了。那麼Java中如何發送一個結構體呢?下面是解決方法:
使用C/S模式,Client為VC6開發,Server為Java,通過Socket通信。
package org.charry.org;
import java.net.*;
/**
*
* 位元組轉換,參考網路文章
*/
class Packet {
private byte[] buf = null;
/**
* 將int轉為低位元組在前,高位元組在後的byte數組
*/
private static byte[] toLH(int n) {
byte[] b = new byte[4];
b[0] = (byte) (n & 0xff);
b[1] = (byte) (n >> 8 & 0xff);
b[2] = (byte) (n >> 16 & 0xff);
b[3] = (byte) (n >> 24 & 0xff);
return b;
}
/**
* 將float轉為低位元組在前,高位元組在後的byte數組
*/
private static byte[] toLH(float f) {
return toLH(Float.floatToRawIntBits(f));
}
/**
* 構造並轉換
*/
public Packet(int packetID, int packetLen, String packetBody) {
byte[] temp = null;
buf = new byte[packetBody.getBytes().length + 8];
temp = toLH(packetID);
System.array(temp, 0, buf, 0, temp.length);
temp = toLH(packetLen);
System.array(temp, 0, buf, 4, temp.length);
System.array(packetBody.getBytes(), 0, buf, 8, packetBody.length());
}
/**
* 返回要發送的數組
*/
public byte[] getBuf() {
return buf;
}
/**
* 發送測試
*/
public static void main(String[] args) {
try {
String tmp = 「test string!」;
Socket sock = new Socket(」127.0.0.1″, 8888);
sock.getOutputStream().write(
new Packet(123, tmp.length(), tmp).getBuf());
sock.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
如果需要用Java 接收結構體的話只需要將上面過程逆過來即可。
⑶ 如何通過Socket TCP發送並接收一個文件
主要是你通過socket api封裝要發送的數據,內部會自動封裝成數據流進行傳輸。
1,什麼是Socket
網路上的兩個程序通過一個雙向的通訊連接實現數據的交換,這個雙向鏈路的一端稱為一個Socket。Socket通常用來實現客戶方和服務方的連接。Socket是TCP/IP協議的一個十分流行的編程界面,一個Socket由一個IP地址和一個埠號唯一確定。
但是,Socket所支持的協議種類也不光TCP/IP一種,因此兩者之間是沒有必然聯系的。在Java環境下,Socket編程主要是指基於TCP/IP協議的網路編程。
2,Socket通訊的過程
Server端Listen(監聽)某個埠是否有連接請求,Client端向Server 端發出Connect(連接)請求,Server端向Client端發回Accept(接受)消息。一個連接就建立起來了。Server端和Client 端都可以通過Send,Write等方法與對方通信。
對於一個功能齊全的Socket,都要包含以下基本結構,其工作過程包含以下四個基本的步驟:
(1) 創建Socket;
(2) 打開連接到Socket的輸入/出流;
(3) 按照一定的協議對Socket進行讀/寫操作;
(4) 關閉Socket.(在實際應用中,並未使用到顯示的close,雖然很多文章都推薦如此,不過在我的程序中,可能因為程序本身比較簡單,要求不高,所以並未造成什麼影響。)
3,創建Socket
創建Socket
java在包java.net中提供了兩個類Socket和ServerSocket,分別用來表示雙向連接的客戶端和服務端。這是兩個封裝得非常好的類,使用很方便。其構造方法如下:
Socket(InetAddress address, int port);
Socket(InetAddress address, int port, boolean stream);
Socket(String host, int prot);
Socket(String host, int prot, boolean stream);
Socket(SocketImpl impl)
Socket(String host, int port, InetAddress localAddr, int localPort)
Socket(InetAddress address, int port, InetAddress localAddr, int localPort)
ServerSocket(int port);
ServerSocket(int port, int backlog);
ServerSocket(int port, int backlog, InetAddress bindAddr)
Socket client = new Socket("127.0.01.", 80);
ServerSocket server = new ServerSocket(80);
在創建socket時如果發生錯誤,將產生IOException,在程序中必須對之作出處理。所以在創建Socket或ServerSocket是必須捕獲或拋出例外。
⑷ java中socket同時傳遞不同類型流的問題
不是很明白你為什麼這么做,一般是只會封裝一個輸入流,不會分開兩個來回獲取數據的。
流底層都是答二進制數據流,無論你用什麼流去讀都是讀同樣的數據,聲明兩個輸出流輸出後,對於客戶端還是只能看到一個流輸入,不會給你分開的。所以這里你開兩個子進程讀,就會出現誰運行快就把數據讀出來了,而且看你PrintWriter也沒有flush,所以應該只傳輸了list數據,客戶端BufferedReader先運行,就把數據讀出來了。
正確的做法是你先要決定伺服器與客戶端的數據交換方式,到底是基於二進制、指定編碼的字元還是對象?看你上面的情況,你想傳輸一個list,二進制和指定編碼字元都比較麻煩,你需要把list通過某種轉換成二進制或者是字元(通常是轉成XML)。比較簡單的就是像你上面那樣傳輸對象,msg是個String對象,本身就可以用ObjectOutputStream傳輸,沒有必要再用一個PrintWriter傳輸。
⑸ java socket如何實現一次傳送多個文件
很簡單,復就是把多制個文件「變成」一個文件傳送就可以了,每個文件都是一個流,把這些流輸入到一個流中合並流傳輸即可,這個是基本思路。實現差不多以下兩個方法
1、直接流拼接,循環要傳輸的文件列表,多個InputStream,然後輸出到一個OutputStream,這個out就是發送數據的埠,為了接收端能夠識別每個文件從而分割流,需要每個流中結尾添加分隔符。其實這就是HTTP文件上傳的做法。
2、就比較簡單了,職業使用ZIP工具包吧需要傳輸的多文件壓縮成一個文件傳輸,接收端直接解壓縮就完事。
需要注意的是,發送多文件上傳你需要提取計算好總傳輸量位元組大小放在傳輸報文頭部告訴接收端你要發送的數據有多大,不然接收端可能無法完整接收數據。
⑹ java socket多文件傳輸問題
參考思路:
1.先傳文件名跟文件大小到 server。
2.開始傳文件。
3.告訴server傳完了。
4.客戶端開始傳下一個,重復123。
參考簡單代碼:
long fileLength;
int readLength;
long totalLength;
for (...)
{
// 讀取文件名
// 讀取文件長度保存到fileLength中
// 將totalLength置為0
while (1)
{
// 讀取數據流,將實際讀取的位元組數保存在readLength中
totalLength += readLength;
if (totalLength >= fileLength) // 一個文件讀取完成,break
// 這樣就差不多了,不過這會把下一個文件的信息讀到當前文件中來。
// 思路是fileLength - totalLength小於等於你設置的緩沖區長度時讀取長度就是fileLength - totalLength
}
}