请问怎样能实现图文混排的发送,就像QQ那样,先从本机里面找出一张图片,放在聊天框里,然后输入文字,按发送,一起发给对方,对方也能收到图片和文字

az1043616292 2012-10-09 11:58:33
请问怎样能实现图文混排的发送,就像QQ那样,先从本机里面找出一张图片,放在聊天框里,然后输入文字,按发送,一起发给对方,对方也能收到图片和文字
请各位高手教教我,怎样将图片和文字的接受端,能同时接收并显示,实现图文混排
图片接收的服务器代码
public void run() {
ServerSocket ss=null;
Socket s=null;
FileOutputStream fos=null;
ObjectInputStream ois=null;
FileInputStream fis=null;// 这个函数的定义和参数绝对不能修改
SimpleAttributeSet textStyle = new SimpleAttributeSet();
String str = null;
AttributeSet attrSet = null;
try {
ss=new ServerSocket(8888);

while (true) {
s = ss.accept();

ois = new ObjectInputStream(s.getInputStream());
File a=(File)ois.readObject();
fos = new FileOutputStream(new File(baocunlj.getText()));

fis=new FileInputStream(a);

while(fis.available()>0){
fos.write(fis.read());

}
fos.close();

textPane.insertIcon(new ImageIcon(baocunlj.getText()));
dic.insertString(dic.getLength(), str+"\n", (javax.swing.text.AttributeSet) attrSet);
textPane.setCaretPosition(dic.getLength());
// 这两句是为了能在接收完图片之后能显示图片

acd++;
baocunlj.setText("f:\\"+acd+".jpg");

}

}
catch (Exception e) {

e.printStackTrace();
}

if(fis!=null)try{fis.close();}catch (IOException e) {}
if(s!=null)try {s.close();} catch (IOException e) {}
if(ss!=null)try {ss.close();} catch (IOException e) {}
}
文字接收端的代码如下

public void run() {
try{
byte buf[]=new byte[1024];
DatagramPacket packet=new DatagramPacket(buf,buf.length);
socket=new MulticastSocket(5555);
while(true){
socket.receive(packet);
String s=new String(buf,0,packet.getLength(),"GBK");
textPane.setText(s+"\n");
packet=new DatagramPacket(buf,buf.length);

}

}catch(Exception e){}
}
...全文
3918 13 打赏 收藏 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
dracularking 2012-10-24
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 的回复:]

把document对象串行化,然后用socket stream发送, 再在接收端接收显示
[/Quote]
整体串化确实不错,这样就不需要再判断里面的内容了吧
nj_dobetter 2012-10-24
  • 打赏
  • 举报
回复
把document对象串行化,然后用socket stream发送, 再在接收端接收显示
dracularking 2012-10-24
  • 打赏
  • 举报
回复
这里有一个发送image的例子,先启动服务端,然后客户端,选择图片,然后它就会通过socket被传输最后显式在客户端上。可以先试试。这个方法要图文并送的话可能不是通过流一次发送,但可以用业务逻辑把n次相连的发送作为业务逻辑上的一次发送。

import java.io.*;
import java.net.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;


public class Server extends JFrame {

ServerSocket ser;
Socket con;
ObjectOutputStream salida;
ObjectInputStream entrada;


public Server() {

}

void ejecutar(){

try{
ser = new ServerSocket( 5700,1 );
con = ser.accept();
salida = new ObjectOutputStream(con.getOutputStream());
salida.flush();
entrada = new ObjectInputStream(con.getInputStream());
procesar();
}
catch(IOException e){}
}

void procesar(){

while(true){
try{

JFileChooser fc=new JFileChooser();
fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
int r = fc.showOpenDialog(this);
File f = fc.getSelectedFile();

salida.writeObject( new ImageIcon(""+f) );


}catch(IOException e){}
}

}

public static void main(String args[]) {
Server srv = new Server();
srv.ejecutar();
}

}

Client:

import java.io.*;
import java.net.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;

public class Cliente extends JFrame {

JTextField tf;
Lienzo lienzo;
Socket con;
ObjectOutputStream salida;
ObjectInputStream entrada;

public Cliente(){

super("Cliente");
Container c = getContentPane();

tf = new JTextField(10);
lienzo=new Lienzo();

c.add(lienzo);
pack();
setSize(100,100);
setVisible(true);
}

void ejecutar(){

try{

con = new Socket("127.0.0.1",5700);
salida = new ObjectOutputStream(con.getOutputStream());
salida.flush();
entrada = new ObjectInputStream(con.getInputStream());

procesar();

}
catch(IOException e){}

}

void procesar() throws IOException {

try{

while(true){
ImageIcon img = (ImageIcon) entrada.readObject();
escribir(img);
}
}catch(ClassNotFoundException e){}

}

void escribir(final ImageIcon img){

SwingUtilities.invokeLater(
new Runnable(){
public void run(){
lienzo.pinta(img);
}

}
);

}

public static void main( String args[] ){
Cliente cl = new Cliente();
cl.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
cl.ejecutar();
}

class Lienzo extends JPanel{

ImageIcon img=null ;

public Lienzo(){

}

public void pinta(ImageIcon img){
this.img=img;
repaint();
}

public void paintComponent(Graphics g){

super.paintComponent(g);

if(img!=null)
img.paintIcon(this,g,10,10);

}


}

}
桃园闲人 2012-10-15
  • 打赏
  • 举报
回复
你怎么用DatagramPacket来通信呀,这是采用UDP的方式来通信的,无法知道是否发送成功,即时消息最好使用tcp的方式。
az1043616292 2012-10-14
  • 打赏
  • 举报
回复
请问怎样判断接收的是字符串,也就是说判断接收的是文字而不是图片,请问是用怎样的语句去判断呢
az1043616292 2012-10-14
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 的回复:]
引用 6 楼 的回复:

请问怎样判断接收的是字符串,也就是说判断接收的是文字而不是图片,请问是用怎样的语句去判断呢

字符串放在message属性上,二进制文件放在image属性上,还需要判断什么呀,直接判断属性是否为null就可以知道有没有放松消息或文件。
[/Quote]
谢谢,虽然你这么说,可能是我理解错误,可是接收端在程序运行的时候必须都开着,等待发送端发送东西,现在既有文字也有图片,也就是说,现在当程序一运行,就要有两个接收端的线程启动,如果不去判断的话,那么程序就会出现错误,不知道是收图片还是收文字,还有一点就是,字符串放在messages属性里面,这个我没用过Messages类,请您教一下相关代码,下面是文字发送和接收,您教一下我怎样用Messages类把字符串,装起来!
代码
发送端
public void sendata(){
try{

String msg=textPane_1.getText();
if(msg.equals(""))
return;
textPane.setText("");
String s="127.0.0.1";
InetAddress MyIP=InetAddress.getLocalHost();
String MI=MyIP.getHostAddress();
InetAddress YourIP=InetAddress.getByName(s);
String sj=new String(""+time.get(GregorianCalendar.YEAR)+
"-"+time.get(GregorianCalendar.MONTH)+
"-"+time.get(GregorianCalendar.DATE)+
"-"+time.get(GregorianCalendar.HOUR)+
":"+time.get(GregorianCalendar.MINUTE)+
":"+time.get(GregorianCalendar.SECOND));
msg="["+MI+"]"+sj+"\n"+msg;

int len=msg.length();
//byte mess[]=new byte[len];
//msg.getBytes(0,len,mess,0);
//msg=new String(packet.getData(),0,packet.getLength(),"GBK");
DatagramPacket packet=new DatagramPacket(msg.getBytes(),msg.getBytes().length,YourIP,5555);
msg=new String(packet.getData(),0,packet.getLength(),"GBK");
socket.send(packet);
Messages message;
}
catch(Exception e1){

}
}



接收
class ThreadForwenzi extends Thread {
public ThreadForwenzi() {

// 构造函数,可以用来传递你所需的某些参数,比如窗体对象,然后将其保存至成员变量中
}
public void run() {
AttributeSet attrSet1 = null;
StringBuffer sb = new StringBuffer();

try{

byte buf[]=new byte[1024];
DatagramPacket packet=new DatagramPacket(buf,buf.length);
socket=new MulticastSocket(5555);
while(true){
socket.receive(packet);
String s=new String(buf,0,packet.getLength(),"GBK");


sb.append(s+"\n");
textPane.setText(sb.toString());

packet=new DatagramPacket(buf,buf.length);

}

}catch(Exception e){}
textPane.setText(sb.toString()+"\n");
sb.append(textPane.getText().toString()+"\n");

}

}
new ThreadForwenzi().start();
桃园闲人 2012-10-14
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 的回复:]

请问怎样判断接收的是字符串,也就是说判断接收的是文字而不是图片,请问是用怎样的语句去判断呢
[/Quote]
字符串放在message属性上,二进制文件放在image属性上,还需要判断什么呀,直接判断属性是否为null就可以知道有没有放松消息或文件。
MiceRice 2012-10-14
  • 打赏
  • 举报
回复
直接判断可没那么容易,尤其是文件本身也许就是个文本文件,那么发送过来跟字符串看起来是完全一样的。


所以正规的通讯协议,在发送正文前,都会发送“消息头”。

消息头中至少会包含:正文类型、长度;如果你学习过HTTP,那么它的消息头信息量海了去了。


具体可以自行设计,比如用 byte[1]作为正文类型,然后 byte[4]作为长度。
az1043616292 2012-10-10
  • 打赏
  • 举报
回复
那请问怎样能判断或者识别,输入或者输出,发送或者接受的是二进制,还是字符串啊,请问能写一下代码来解释一下吗,

例如写个if的判断语句,怎样能判断if(接收的东西是二进制),则转换为图片发送和接收的通道,


else if(接收的东西是字符串),则转换为文字的发送和接收的通道,能用这样的方法跟我解释一下吗,


本人,实力水平不高,请各位高手大侠教一教
hsliwei 2012-10-09
  • 打赏
  • 举报
回复
页面传过来两个对象,如果不为空就都发送
az1043616292 2012-10-09
  • 打赏
  • 举报
回复
谢谢,能具体点吗,还有图片发送功能是直接用流发送到对方机子里面再显示的方法
桃园闲人 2012-10-09
  • 打赏
  • 举报
回复
用对象流,图片放到二进制数组中,文本放到字符串中。
桃园闲人 2012-10-09
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]

用对象流,图片放到二进制数组中,文本放到字符串中。
[/Quote]
将图片和消息分别放到某个对象的属性上,如message、image,这两个属性,如果还有其他的信息可以在扩展。通过Socket建立服务器和客户端的链接,然后通过ObjectInputStream和ObjectInputStream发送和接收数据,图片数组到了接收方后转换成图片文件存放在硬盘上,然后通过路劲指向片面文件将其显示出来,文本信息直接显示。

62,620

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧