高手帮忙看下下面两段代码有么问题哈:为什么两数和结果不能显示阿 而且服务段连接为什么非得点击“发送”按钮才能显示已连接哦 我想点击 连接时就连接上哦
1:Server
package text2;
import javax.swing.*;
import java.awt.event.*;
import java.net.*;
import java.io.*;
public class Server {
public static void main(String[] args) throws Exception{
new Servers();
}
}
//服务端
class Servers extends JFrame implements ActionListener{
/**
*
*/
private static final long serialVersionUID = -57473977679152807L;
Socket client=null;
ServerSocket server;
PrintWriter out;
BufferedReader buf;
JLabel lab=new JLabel("端口号");
JTextField txt=new JTextField("9999");
JButton cbd=new JButton("侦听");
public Servers(){
super("通信服务端");
this.setLayout(null);
this.setLocation(150,300);
this.setSize(320,170);
this.setVisible(true);
this.setResizable(false);
this.add(txt);
this.add(lab);
this.add(cbd);
lab.setSize(40,40);
txt.setSize(70,40);
cbd.setSize(130,40);
lab.setLocation(30,50);
txt.setLocation(75,50);
cbd.setLocation(180,50);
cbd.addActionListener(this);
}
public void actionPerformed(ActionEvent e) {
try{
System.out.println("等待客户端的连接请求");
int port=Integer.valueOf(txt.getText());
listening(port);
buf=new BufferedReader(new InputStreamReader(client.getInputStream()));
String str=buf.readLine();
String a[]=str.split("//+");
String b=String.valueOf(Integer.valueOf(a[0])+Integer.valueOf(a[1]));
out=new PrintWriter(client.getOutputStream());
out.println(b);
out.flush();
}catch(Exception ex){}
}
public void listening(int p){
try{
server=new ServerSocket(p);
client=server.accept();//等待,一直到客户端连接才望下执行
cbd.setText("客户端已连接");
}catch(Exception e){}
}
}
2:Client
package text2;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import java.net.*;
public class Client {
public static void main (String[] args) throws Exception{
new Main();
}
}
class Main extends JFrame implements ActionListener {
private static final long serialVersionUID = 1L;
/**
* @param args
*/
//定义属性值
int width=Toolkit.getDefaultToolkit().getScreenSize().width;
int height=Toolkit.getDefaultToolkit().getScreenSize().height;
BorderLayout f=new BorderLayout();
JTextField txt1=new JTextField();//显示输入的数字
JLabel lab=new JLabel("请输入两个数相加形如: a+b");
JTextField txt2=new JTextField("127.0.0.1");//显示服务端地址
JLabel lab2=new JLabel("=");
JButton cbd2=new JButton("连接");//连接按钮
JButton cbd=new JButton("发送");//发送按钮
JTextField txt3=new JTextField();//显示结果
JPanel p=new JPanel();
JPanel p2=new JPanel();
JPanel p3=new JPanel();
JLabel lab3=new JLabel("服务端地址");
JLabel lab4=new JLabel("连接端口");
JTextField txt4=new JTextField("9999");//显示端口号
String str;
Socket client;
BufferedReader in;
PrintWriter out;
//定义构造方法去完成客户端的GUI界面绘制
public Main() throws Exception{
super("通信客户端");
p.setLayout(f);
txt1.setColumns(13);
cbd.addActionListener(this);
cbd2.addActionListener(this);
//cbd.setFont(font)
txt3.setColumns(6);
txt2.setColumns(15);
txt4.setColumns(8);
this.add(p,BorderLayout.CENTER);
p.add(p2,BorderLayout.NORTH);
p.add(p3,BorderLayout.CENTER);
p2.add(lab3);
p2.add(txt2);
p2.add(lab4);
p2.add(txt4);
p2.add(cbd2);
p3.add(lab);
p3.add(txt1);
p3.add(cbd);
p3.add(lab2);
p3.add(txt3);
this.setSize(600,120);
this.setLocation((width-400)/2,(height-300)/2);
this.setVisible(true);
this.setResizable(false);
}
//定义两个按钮的事件
public void actionPerformed(ActionEvent e) {
try{
if(e.getSource()==cbd2){//按钮连接事件
String ip=txt2.getText().trim();
int port=Integer.parseInt(txt4.getText().trim());
cbd2.setText("正在连接...");
client=new Socket(ip,port);
cbd2.setText("连接完成");
}
if(e.getSource()==cbd){//按钮发送事件
str=txt1.getText().trim();
senddata(str);
in=new BufferedReader(new InputStreamReader(client.getInputStream()));
while(in.ready()){
txt3.setText(in.readLine());
}
}
}catch( Exception ex){}
}
//定义发送按钮触发的发送数据的方法
public void senddata(String s) throws Exception{
out=new PrintWriter(client.getOutputStream());
out.println(s);
out.flush();
}
}
1:Server
package text2;
import javax.swing.*;
import java.awt.event.*;
import java.net.*;
import java.io.*;
public class Server {
public static void main(String[] args) throws Exception{
new Servers();
}
}
//服务端
class Servers extends JFrame implements ActionListener{
/**
*
*/
private static final long serialVersionUID = -57473977679152807L;
Socket client=null;
ServerSocket server;
PrintWriter out;
BufferedReader buf;
JLabel lab=new JLabel("端口号");
JTextField txt=new JTextField("9999");
JButton cbd=new JButton("侦听");
public Servers(){
super("通信服务端");
this.setLayout(null);
this.setLocation(150,300);
this.setSize(320,170);
this.setVisible(true);
this.setResizable(false);
this.add(txt);
this.add(lab);
this.add(cbd);
lab.setSize(40,40);
txt.setSize(70,40);
cbd.setSize(130,40);
lab.setLocation(30,50);
txt.setLocation(75,50);
cbd.setLocation(180,50);
cbd.addActionListener(this);
}
public void actionPerformed(ActionEvent e) {
try{
System.out.println("等待客户端的连接请求");
int port=Integer.valueOf(txt.getText());
listening(port);
buf=new BufferedReader(new InputStreamReader(client.getInputStream()));
String str=buf.readLine();
String a[]=str.split("//+");
String b=String.valueOf(Integer.valueOf(a[0])+Integer.valueOf(a[1]));
out=new PrintWriter(client.getOutputStream());
out.println(b);
out.flush();
}catch(Exception ex){}
}
public void listening(int p){
try{
server=new ServerSocket(p);
client=server.accept();//等待,一直到客户端连接才望下执行
cbd.setText("客户端已连接");
}catch(Exception e){}
}
}
2:Client
package text2;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import java.net.*;
public class Client {
public static void main (String[] args) throws Exception{
new Main();
}
}
class Main extends JFrame implements ActionListener {
private static final long serialVersionUID = 1L;
/**
* @param args
*/
//定义属性值
int width=Toolkit.getDefaultToolkit().getScreenSize().width;
int height=Toolkit.getDefaultToolkit().getScreenSize().height;
BorderLayout f=new BorderLayout();
JTextField txt1=new JTextField();//显示输入的数字
JLabel lab=new JLabel("请输入两个数相加形如: a+b");
JTextField txt2=new JTextField("127.0.0.1");//显示服务端地址
JLabel lab2=new JLabel("=");
JButton cbd2=new JButton("连接");//连接按钮
JButton cbd=new JButton("发送");//发送按钮
JTextField txt3=new JTextField();//显示结果
JPanel p=new JPanel();
JPanel p2=new JPanel();
JPanel p3=new JPanel();
JLabel lab3=new JLabel("服务端地址");
JLabel lab4=new JLabel("连接端口");
JTextField txt4=new JTextField("9999");//显示端口号
String str;
Socket client;
BufferedReader in;
PrintWriter out;
//定义构造方法去完成客户端的GUI界面绘制
public Main() throws Exception{
super("通信客户端");
p.setLayout(f);
txt1.setColumns(13);
cbd.addActionListener(this);
cbd2.addActionListener(this);
//cbd.setFont(font)
txt3.setColumns(6);
txt2.setColumns(15);
txt4.setColumns(8);
this.add(p,BorderLayout.CENTER);
p.add(p2,BorderLayout.NORTH);
p.add(p3,BorderLayout.CENTER);
p2.add(lab3);
p2.add(txt2);
p2.add(lab4);
p2.add(txt4);
p2.add(cbd2);
p3.add(lab);
p3.add(txt1);
p3.add(cbd);
p3.add(lab2);
p3.add(txt3);
this.setSize(600,120);
this.setLocation((width-400)/2,(height-300)/2);
this.setVisible(true);
this.setResizable(false);
}
//定义两个按钮的事件
public void actionPerformed(ActionEvent e) {
try{
if(e.getSource()==cbd2){//按钮连接事件
String ip=txt2.getText().trim();
int port=Integer.parseInt(txt4.getText().trim());
cbd2.setText("正在连接...");
client=new Socket(ip,port);
cbd2.setText("连接完成");
}
if(e.getSource()==cbd){//按钮发送事件
str=txt1.getText().trim();
senddata(str);
in=new BufferedReader(new InputStreamReader(client.getInputStream()));
while(in.ready()){
txt3.setText(in.readLine());
}
}
}catch( Exception ex){}
}
//定义发送按钮触发的发送数据的方法
public void senddata(String s) throws Exception{
out=new PrintWriter(client.getOutputStream());
out.println(s);
out.flush();
}
}
//定义两个按钮的事件
public void actionPerformed(ActionEvent e) {
try{
if(e.getSource()==cbd2){//按钮连接事件
String ip=txt2.getText().trim();
int port=Integer.parseInt(txt4.getText().trim());
cbd2.setText("正在连接...");
client=new Socket(ip,port);
cbd2.setText("连接完成");
}
if(e.getSource()==cbd){//按钮发送事件str=txt1.getText().trim();
senddata(str);
in=new BufferedReader(new InputStreamReader(client.getInputStream()));
while(in.ready()){
txt3.setText(in.readLine());
}
}
}catch( Exception ex){}
}
不能加,两个数不显示是因为你这里错误了
client都没初始化 还是null 你就getInputStream() 发生空指针异常了你这程序漏洞百出啊、、、捕获异常竟然什么都表示,那你捕获了有什么用
自己好好改改吧 要不就先放一下吧 多积累一下再去看可能好些
1 服务器端,server.accept();是放在按钮事件里,而server.accept();本身会造成线程堵塞,所以必须有客户端连接时,server.accept();后面的代码才会继续被执行,所以,只有你点了客户端的连接,服务器端才会显示客户端已连接
2 程序中server.accept();只有一次,也就是服务器端的按钮不点,就不会触发server.accept();也就不会监听客户端,所以服务器每次要接受客户端信息,都要点一次按钮,这应该不是LZ你想要的结果吧
3 服务器端发送信息时,如果发生Exception,那么客户端就一直陷入线程等待状态,也就是说如果服务器端出错,客户端不但没有显示,也会一直停留在readLine方法中
4 socket同心,最好不要采用readLine方法读取数据,因为readLine要遇到(回车)换行符才行,而你发送数据就要自己保证把这些字符也带上
5 你的客户端只能一次发送数据,第二次再发送数据时,首先上面说了,server.accept();只有一次,所以如果想再接收,必须点服务器端的按钮,其次,因为server.accept();堵塞,所以客户端必须点连接才能继续通信,这样,应该也不是LZ你想要的结果
等等,综上所述,建议
1 把server.accept();方法一个线程里,并且该先程用个while循环一直调用server.accept();这样,你的服务器端的按钮就不需要等待了
2 对于每次socket,服务器端可以采用一个线程跟其通信,这样,你的客户端就可以多次发送信息了
3 不要用readLine方法,改为InputStream的read方法,可以直接使用socket.getInputStream().read(),把数据读到一个数组里,然后对数组进行处理for example
class ServerThread extends Thread {
ServerSocket server;
boolean flag = true;
public ServerThread(ServerSocket server) {
this.server = server;
start();
}
public void run() {
try {
while (flag) {
Socket client = server.accept();
System.out.println("client connected");
new SocketThread(client); //用一个线程来对应一个socket,如果线程太多,可以考虑用线程池,通过队列的方式对每个socket处理
yield();
}
} catch (Exception e) { }
}
} class SocketThread extends Thread {
Socket socket;
public SocketThread(Socket socket) {
this.socket = socket;
start();
} public void run() {
try {
while (true) {
byte[] data = new data[1024];
socket.getInputStream().read(data);
String str = new String(data).trim();
String a[] = str.split("\\+");
String b = String.valueOf(Integer.valueOf(a[0])+Integer.valueOf(a[1]));
socket.getOutputStream().write(b.getBytes());
yield();
}
} catch (Exception e) { }
}
}//修改你的事件
public void actionPerformed(ActionEvent e) {
try{
System.out.println("等待客户端的连接请求");
int port=Integer.valueOf(txt.getText());
//listening(port);
//buf=new BufferedReader(new InputStreamReader(client.getInputStream()));
//String str=buf.readLine(); //String a[]=str.split("//+");
//String b=String.valueOf(Integer.valueOf(a[0])+Integer.valueOf(a[1]));
//out=new PrintWriter(client.getOutputStream());
//out.println(b);
//out.flush();
server = new ServerSocket(port);
ServerThread serverThread = new ServerThread(server);
cbd.setText("服务器端开始监听");
}catch(Exception ex){}
}
即class SocketThread extends Thread {
Socket socket;
public SocketThread(Socket socket) {
this.socket = socket;
start();
} public void run() {
try {
while (true) {
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String str = reader.readLine();
String a[] = str.split("\\+");
String b = String.valueOf(Integer.valueOf(a[0])+Integer.valueOf(a[1]));
BufferedWriter writer = new BufferedWriter(new OutputStreamReader(socket.getOutputStream()));
writer.write(b);
writer.newLine(); //换行
writer.flush();
yield();
}
} catch (Exception e) { }
}
}//客户端
public void senddata(String s) throws Exception{
//out=new PrintWriter(client.getOutputStream());
//out.println(s);
//out.flush();
BufferedWriter writer = new BufferedWriter(new OutputStreamReader(client.getOutputStream()));
writer.write(b);
writer.newLine(); //换行
writer.flush();
}
2 Socket编程注意一些阻塞点,如accept/read/readline等,写到这些地方的时候,就要想到线程可能就会停在这,必须小心设计避免锁住:C/S两端就要定好协议,哪个先哪个后、哪个发哪个接,等等