java中socket编程消息传递问题

glzlaohuai 2009-11-17 05:59:01
服务器端代码:
import java.net.*;
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
import java.util.*;
public class Server extends JFrame
{
private int port; //端口号
private JTextField jtf1=new JTextField();
private JTextArea jta=new JTextArea();
private JButton b=new JButton("建立");
private LinkedList<ServerHander> clientList=new LinkedList<ServerHander>();
private int num=0;
public Server()
{
JPanel p1=new JPanel();
p1.setLayout(new BorderLayout());
p1.add(jtf1,BorderLayout.CENTER);
p1.setBorder(new TitledBorder("端口号(0~65535)"));


JPanel p2=new JPanel();
p2.setLayout(new BorderLayout());
p2.add(b,BorderLayout.CENTER);

JPanel p3=new JPanel();
p3.setLayout(new GridLayout(1,2));
p3.add(p1);
p3.add(p2);

this.setLayout(new BorderLayout());
this.add(p3,BorderLayout.NORTH);
this.add(jta,BorderLayout.CENTER);

//jta.setEditable(false);
jtf1.setToolTipText("服务器将监听试图连接到此端口上的客户端");
b.addActionListener(new ButtonAct());
}
public static void main(String args[])
{
Server frame=new Server();
frame.setBounds(100,150,400,100);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("服务器端");
frame.setVisible(true);
}
class ButtonAct implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
try
{
port=Integer.parseInt(jtf1.getText().trim());
if((port>65535)||(port<0))
{
jta.append("请在一个适当的端口上启动服务器!"+"\n");
}
ServerSocket ss=new ServerSocket(port);
jta.append("服务器成功启动于 :"+port);
System.out.println("服务器成功启动于 :"+port);
jta.append("\n"+new Date()+"\n");
System.out.println(new Date());
b.setEnabled(false);
Socket s;
String name;
while(true)
{
s=ss.accept();
num++;
DataInputStream fromClient=new DataInputStream(s.getInputStream());
name=fromClient.readUTF();
System.out.println("有新的成员加入,ip: "+s.getInetAddress()+"昵称 :"+name+" "+new Date());
System.out.println("现有成员数"+num);
jta.append("有新的成员加入,ip: "+s.getInetAddress()+" "+"昵称 :"+name+"\n");
jta.append("现在的成员数:"+num);
ServerHander sh=new ServerHander(name,s);
sh.start();
}
}
catch(IOException ex)
{
ex.printStackTrace();
}
}
}
class ServerHander extends Thread
{
String name;
Socket s;
DataInputStream fromClient;
DataOutputStream toClient;
String msg;
ServerHander(String name,Socket s)
{
this.name=name;
this.s=s;
}
ServerHander()
{
;
}
public void run()
{
clientList.add(this);
try
{
fromClient=new DataInputStream(s.getInputStream());
toClient=new DataOutputStream(s.getOutputStream());
sendAllClient(new Date()+" Server");
sendAllClient(name+" 进入***************");
while(true)
{
msg=fromClient.readUTF();
sendAllClient(msg);
}
}
catch(Exception ex)
{
clientList.remove(this);
num--;
System.out.println(name+"离开 "+new Date());
sendAllClient(name+" 离开********************");
}
}
public void sendAllClient(String msg) //给所有的客户端传送信息
{
Iterator i=clientList.iterator();
ServerHander sh;
while(i.hasNext())
{
sh=(ServerHander)i.next();
try
{
sh.toClient.writeUTF(msg);
sh.toClient.flush();
}
catch(IOException ex)
{
ex.printStackTrace();
}
}
}
}
}

客户端代码:
import java.net.*;
import java.io.*;
import javax.swing.*;
import javax.swing.border.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class Client extends JFrame
{
private JTextField jtf1=new JTextField(); //端口号
private JTextField jtf2=new JTextField(); //ip地址
private JTextField jtf3=new JTextField(); //昵称
private JTextArea jta1=new JTextArea();
private JTextArea jta2=new JTextArea();
private JButton b=new JButton("登录");
public Client()
{
JPanel p1=new JPanel();
p1.setLayout(new BorderLayout());
p1.add(jtf1,BorderLayout.CENTER);
p1.setBorder(new TitledBorder("服务器的IP地址"));

JPanel p2=new JPanel();
p2.setLayout(new BorderLayout());
p2.add(jtf2,BorderLayout.CENTER);
p2.setBorder(new TitledBorder("服务器所监听的端口号"));


JPanel p3=new JPanel();
p3.setLayout(new BorderLayout());
p3.add(jtf3,BorderLayout.CENTER);
p3.setBorder(new TitledBorder("你的昵称"));


JPanel p4=new JPanel();
p4.setLayout(new GridLayout(1,3));
p4.add(p1);
p4.add(p2);
p4.add(p3);


JPanel p6=new JPanel();
p6.add(b);


jta1.setEditable(false);
//jta1.setBackground(Color.green);
//jta2.setBackground(Color.BLUE);
//jta2.setForeground(Color.MAGENTA);


JScrollPane jsp1=new JScrollPane(jta1);


JScrollPane jsp2=new JScrollPane(jta2);


JSplitPane jsp=new JSplitPane(JSplitPane.VERTICAL_SPLIT,jsp1,jsp2);
jsp.setDividerLocation(300);
jsp.setDividerSize(15);

b.addActionListener(new ButtonAct());

this.setLayout(new BorderLayout());
this.add(p4,BorderLayout.NORTH);
this.add(jsp,BorderLayout.CENTER);
this.add(p6,BorderLayout.SOUTH);
}
public static void main(String args[])
{
Client frame=new Client();
frame.setBounds(100,150,800,500);
frame.setTitle("客户端");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
class ButtonAct implements ActionListener
{
DataInputStream fromServer;
DataOutputStream toServer;
String msg;
public void actionPerformed(ActionEvent e)
{
int port;
String ip;
String name;
ip=jtf1.getText().trim();
port=Integer.parseInt(jtf2.getText().trim());
name=jtf3.getText().trim();
try
{
Socket s=new Socket(ip,port);
b.setEnabled(false);
fromServer=new DataInputStream(s.getInputStream());
toServer=new DataOutputStream(s.getOutputStream());
toServer.writeUTF(name);
jta2.addKeyListener(new TextAct());
while(true)
{
msg=fromServer.readUTF();
jta1.append(msg+"\n");
}
}
catch(Exception ex)
{
jta1.append("错误的ip地址或者端口号,或者服务器未启动"+"\n");
b.setEnabled(true);
}
}
class TextAct extends KeyAdapter
{
public void keyPressed(KeyEvent e)
{
if(e.getKeyCode()==10)
{
try
{
toServer.writeUTF(jta2.getText());
}
catch(IOException ex)
{
ex.printStackTrace();
}
jta2.setText("");
}
}
}
}
}

客户端只要点击登录按钮,就一直处于无反应状态~,哪位指点一下啊。
...全文
197 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
bawgiitx 2009-11-17
  • 打赏
  • 举报
回复

private Thread thr;//加线程

public void actionPerformed(ActionEvent e)
{
if(thr==null||!thr.isAlive(){

int port;
String ip;
String name;
ip=jtf1.getText().trim();
port=Integer.parseInt(jtf2.getText().trim());
name=jtf3.getText().trim();
try
{
Socket s=new Socket(ip,port);
b.setEnabled(false);
fromServer=new DataInputStream(s.getInputStream());
toServer=new DataOutputStream(s.getOutputStream());
toServer.writeUTF(name);
jta2.addKeyListener(new TextAct());
thr=new Thread(new Runnable(){
public void run(){
while(true)
{
msg=fromServer.readUTF();
jta1.append(msg+"\n");
}
}});
thr.start();
}
catch(Exception ex)
{
jta1.append("错误的ip地址或者端口号,或者服务器未启动"+"\n");
b.setEnabled(true);
}
}
}

icekay Song 2009-11-17
  • 打赏
  • 举报
回复
read()方法是个阻塞方法,如果服务器不发数据你岂不是一直等下去...一般只监听发送,接收另起线程.
designedIt 2009-11-17
  • 打赏
  • 举报
回复
客户端只要点击登录按钮,就一直处于无反应状态~。。。

肯定会“无反应状态”啊,你都在“登录按钮”中有一个
while(true)
{
msg=fromServer.readUTF();
jta1.append(msg+"\n");
}

了,当然会“无反应状态”。
办法:
将“登录按钮”中代码改造成一个线程。当单击“登录按钮”时,产生一个线程并启动它就行了。

62,614

社区成员

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

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