私は画像だけでなく文字列メッセージも送信したい.私は、ユーザーが画像とチャット(文字列)を共有できるAndroidチャットアプリケーションを設計しています.Javaサーバーはリッスンしてブロードキャストするバックエンドにあります. 私はいくつかの記事を読んでいますが、まだ混乱しています。1)データを送信し、受信サーバーでその文字列または画像を知るにはどうすればよいですか?2) イメージと文字列をそれぞれリッスンしてからブロードキャストするための個別のソケットが必要です 3) 文字列とイメージをバイト配列で保持し、Java サーバーに渡すことができるオブジェクトを使用できますか? objectoutputstream/dataoutputstreamを使用してそれを達成する必要があるかどうかも混乱しています。
3 に答える
Keep Seperate Sockets that makes it simpler,or you need syncronisation
1)use objectoutputstream for image thats fastest method of image transfer
2)use dataoutputstream for string
Image Sending code
File myFile = new File ("d:\\ab.jpg");
byte [] mybytearray = new byte [(int)myFile.length()];
FileInputStream fis = new FileInputStream(myFile);
BufferedInputStream bis = new BufferedInputStream(fis);
bis.read(mybytearray,0,mybytearray.length);
OutputStream os = sock.getOutputStream();
System.out.println("Sending...");
os.write(mybytearray,0,mybytearray.length);
os.flush();
os.close();
Image receiving code
int filesize=6022386; // filesize temporary hardcoded
long start = System.currentTimeMillis();
int bytesRead;
int current = 0;
File f=new File("d:\\ab.jpg");
f.createNewFile();
// receive file
byte [] mybytearray = new byte [filesize];
InputStream is = socket.getInputStream();
FileOutputStream fos = new FileOutputStream(f);
BufferedOutputStream bos = new BufferedOutputStream(fos);
bytesRead = is.read(mybytearray,0,mybytearray.length);
current = bytesRead;
do {
bytesRead =
is.read(mybytearray, current, (mybytearray.length-current));
if(bytesRead >= 0) current += bytesRead;
} while(bytesRead > -1);
count=current;
Copy=mybytearray.clone();
bos.write(mybytearray, 0 , current);
bos.flush();
long end = System.currentTimeMillis();
System.out.println(end-start);
bos.close();
fos.close();
Status=true;
アプリケーション層プロトコルのすべての理由を発見しました。ソケット自体は、バイトを送信する方法を提供するだけで、バイトの意味については何も言いません。ここで、アプリケーション層プロトコルの出番です。
イメージまたはデータのタイプ バイト (0 または 1) を最初に送信するプロトコルを設計できます。次に、長さ (データまたはイメージの長さ) に整数 (4 バイト) が必要になる場合もあります。これにより、受信側は最初にそれらを読み取り、受信するバイト数と、それらのバイトがデータまたは画像を表すかどうかを知ることができます。
JavaSerializable
インターフェイスを確認してください: http://docs.oracle.com/javase/6/docs/api/java/io/Serializable.html
要約すると、実装するクラスSerializable
は、そのすべてのフィールドも である場合、追加の作業なしでシリアル化できますSerializable
。そう:
public class Message<Img_Type> implements Serializable {
protected String mText = null;
protected <Img_Type> mImage = null; // Img_Type must implement Serializable
// ... constructor(s), get/set methods
}
Socket
その後、 、ObjectInputStream
、およびを使用して、これらのオブジェクトを読み書きできますObjectOutputStream
。読むには(1つ)Message
:
Socket socket; // initialize your socket
Message msg;
try {
InputStream is = socket.getInputStream();
ObjectInputStream ois = new ObjectInputStream(is);
Message msg = (Message) ois.readObject();
ois.close();
} catch (ClassNotFoundException e) {
// handle exception
}
// handle message
a の書き込みは、Message
を使用して同様の方法で行うことができますObjectOutputStream
。この例では、Message
フィールドを照合null
して内容を確認できます。
意識すべきことの 1 つは、コンストラクターが入力ストリームからObjectInputStream
an のヘッダーを読み取るまで返さないことです。たとえば、aを受信する準備ができています。さらに、サーバーでオブジェクト入力ストリームを閉じると、対応する出力ストリームが開いている場合はクライアントで例外がスローされ、その逆も同様です。Object
Message