首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > J2SE开发 >

TCP编程socket小疑点

2013-04-09 
TCP编程socket小问题import java.io.IOExceptionimport java.io.PrintWriterimport java.net.Socketimp

TCP编程socket小问题

import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.ArrayList;

public class SocketManager extends ArrayList {
synchronized void add(Socket socket){
super.add(socket);
}
synchronized void delete(Socket socket){
super.remove(socket);
}
synchronized void sendClientCount(){
String info = "当前聊天人数"+size();
System.out.println(info);
writeAll(info);
}
synchronized void writeAll(String str){
PrintWriter writer = null;
Socket socket;
for(int i=0;i<size();i++){
socket = (Socket)get(i);
try {
writer = new PrintWriter(socket.getOutputStream(),true);//创建输出流
if(writer != null){
writer.println(str);//通过输出流写入信息
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
}

}


服务器端程序:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;


public class ServerProcess {
private SocketManager socketMan = new SocketManager();

void getServer(){
try{
ServerSocket serverSocket = new ServerSocket(7777);
System.out.println("服务器套接字已创建");
while(true){
Socket socket = serverSocket.accept(); //等待连接
new write_Thread(socket).start();//启动线程
socketMan.add(socket);//添加套接字
socketMan.sendClientCount();//将连接数输出
}
}catch(Exception e){
e.printStackTrace();
}
}

class write_Thread extends Thread{
Socket socket = null;
private BufferedReader reader;
public write_Thread(Socket socket){
this.socket = socket;
}
public void run(){
try{
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String msg;
while((msg=reader.readLine())!= null){
//System.out.println(msg);
socketMan.writeAll(msg);
}
}catch(Exception e){
e.printStackTrace();
}
}
}
public static void main(String[] args){
ServerProcess server = new ServerProcess();
server.getServer();
}
}

客户端程序:

import java.awt.event.*;
import java.io.*;
import java.net.*;
import javax.swing.*;
public  class Client2 extends JFrame{
private static final long serialVersionUID = 1L;
private JPanel jpanel = new JPanel();
private JLabel nameLabel = new JLabel("姓名:");
private JTextField nameField = new JTextField();
private JTextArea msgArea = new JTextArea();
private JTextField sendField = new JTextField();
private JScrollPane jScrollPanel = new JScrollPane();
private BufferedReader reader;
private PrintWriter writer;
private Socket socket;
public Client2(String title){
super(title);


this.setSize(360,340);
this.add(jpanel);
jpanel.setLayout(null);
msgArea.setEditable(false);
jpanel.add(nameLabel);
nameLabel.setBounds(10,10,60,20);
jpanel.add(nameField);
nameField.setBounds(60,10,270,21);
jpanel.add(sendField);
sendField.setBounds(10,270,320,21);
msgArea.setColumns(20);
msgArea.setRows(5);
jScrollPanel.setViewportView(msgArea);
jpanel.add(jScrollPanel);
jScrollPanel.setBounds(10,40,320,220);
sendField.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e){
writer.println(nameField.getText()+":"+sendField.getText());
sendField.setText("");
}
});
}
void getSocket(){
msgArea.append("尝试与服务器连接");
try{
socket = new Socket("127.0.0.1",7777);
msgArea.append("聊天准备完毕");
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
writer = new PrintWriter(socket.getOutputStream(),true);
while(true){
msgArea.append(reader.readLine()+"\n");
}
}catch(Exception e){
e.printStackTrace();
}
}
public static void main(String[] args){
Client2 client = new Client2("迷你聊天屋");
client.setVisible(true);
client.getSocket();
}
}



在客户端有个while(true)不断将内容读取出来,但是在服务器端是如何不断读取客户端发过来的内容的呢?while((msg=reader.readLine())!= null){这句不是只能执行一次吗?符合条件就向下执行了,还会再来进行判断吗?具体是怎么运行的?知道的请讲解一下! socket tcp
[解决办法]
引用:
引用:我懂你的意思 了,你的意思是你输入一行别人输入一行,而你再输入的时候服务器还可以读取你不明白是吧?
我输入一行的时候,reader.readLine()读取完了,不就返回null了吗?如何阻塞?

你考虑到你的组件的线程特性了吗?键盘侦听是一直不释放线程的。阻塞是通过你组件来完成的。
[解决办法]
引用:
引用:引用:
引用:reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                String msg;
                wh……
只有读到数据流最末尾,才返回null
在网络上,一直等待输入,即使是对方什么也不输入,只是回车,readline也不会返回null
如果I/O中断,会返回I/O异常,还是不会返回null
除非你使用的数据流有固定长度(比如文件数据流,或者ByteArrayInputStream之类),而不是网络数据流(阻塞模式)。也就是说在网络数据流下,不会返回null的。
所以可以执行以下操作:
在I/O阻塞模式下:
      while((line = in.readLine()) != null)
改成:
      while(网络状态)//状态可由从客户端读入数据时捕捉I/O异常来获取

热点排行