一个简单的服务器端与多个客户端进行通信,
每次都是服务器先运行,那么端口就已经确定了,那么就只能与一个客户端进行通信,
我想加入多线程,实现多人通信,但是不知怎么样使用多个端口???
我想根据客户端所使有的端口来确定服务器端使用的端口,但不知怎么实现???不知一般多线程中,这个端口问题该如何解决????
每次都是服务器先运行,那么端口就已经确定了,那么就只能与一个客户端进行通信,
我想加入多线程,实现多人通信,但是不知怎么样使用多个端口???
我想根据客户端所使有的端口来确定服务器端使用的端口,但不知怎么实现???不知一般多线程中,这个端口问题该如何解决????
while(true){
socket=serverSocket.accept();
分配一个线程:如 new 线程名(socket);
}
然后将事件交给线程来处理就行了
想了很久没想明白,是为什么???试着写的一人简单通信程序,为什么服务器只能与一个客户进行通信,而其它客户发的信息,服务器接收不到呢????服务器端的程序:
import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.io.*;
import javax.swing.*;public class J_ChatServer extends JFrame
{
public static ObjectInputStream m_input; // 输入流
public static ObjectOutputStream m_output; // 输出流
public static JTextField m_enter; // 输入区域
public static JTextArea m_display; // 显示区域
public static int m_clientNumber = 0; // 连接的客户数
//服务器端界面设计
public J_ChatServer( ) // 在图形界面中添加组件
{
super("聊天程序服务器端");
Container c = getContentPane( );
m_enter = new JTextField( );
m_enter.setEnabled( false );
m_enter.addActionListener(new ActionListener( )
{
public void actionPerformed( ActionEvent event )
{ // 向客户端发送数据
try
{
String s = event.getActionCommand( );
m_output.writeObject( s );
m_output.flush( );
mb_displayAppend( "服务器端: " + s );
m_enter.setText( "" ); // 清除输入区域的原有内容
}
catch (Exception e)
{
System.err.println("发生异常:" + e);
e.printStackTrace( );
} // try-catch结构结束
} // 方法actionPerformed结束
} // 实现接口ActionListener的内部类结束
); // addActionListener方法调用结束
c.add( m_enter, BorderLayout.NORTH );
m_display = new JTextArea( );
c.add( new JScrollPane( m_display ), BorderLayout.CENTER );
} // J_ChatServer构造方法结束
//对显示区进行处理,使显示区能显示出最新聊天记录
public static void mb_displayAppend( String s )
{
m_display.append( s + "\n" );
m_display.setCaretPosition( m_display.getText( ).length( ) );
m_enter.requestFocusInWindow( ); // 转移输入焦点到输入区域
} // 方法mb_displayAppend结束
//通知客户端,聊天程序已结束
public static boolean mb_isEndSession( String m )
{
if (m.equalsIgnoreCase("q"))
return(true);
if (m.equalsIgnoreCase("quit"))
return(true);
if (m.equalsIgnoreCase("exit"))
return(true);
if (m.equalsIgnoreCase("end"))
return(true);
if (m.equalsIgnoreCase("结束"))
return(true);
return(false);
} // 方法mb_isEndSession结束
//启动服务器
public void mb_run( )
{
try
{
ServerSocket server = new ServerSocket(5000);
String m; // 来自客户端的消息
while (true)
{
m_clientNumber++;
mb_displayAppend("等待连接[" + m_clientNumber + "]");
Socket s = server.accept( ); //每联结到一个新的客户,就启动一个新的线程
MyThread mythread=new MyThread(s);
mythread.start();
} // while循环结束
}
catch (Exception e)
{
System.err.println("发生异常:" + e);
e.printStackTrace( );
mb_displayAppend("连接[" + m_clientNumber + "]发生异常");
} // try-catch结构结束
} // 方法mb_run结束 public static void main(String args[ ])
{
J_ChatServer app = new J_ChatServer( ); app.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE);
app.setSize(350, 150);
app.setVisible(true);
app.mb_run( );
} // 方法main结束
} // 类J_ChatServer结束
//构造一个线程类,实现服务器同时与多个客户进行聊天
class MyThread extends Thread
{
Socket s;
String m; // 来自客户端的消息
public MyThread(Socket s)
{
this.s=s;
}
public void run() //实现与客户端的通信
{
try
{
J_ChatServer.mb_displayAppend("接收到客户端连接[" + J_ChatServer.m_clientNumber + "]");
J_ChatServer.m_output = new ObjectOutputStream( s.getOutputStream( ) );
J_ChatServer.m_input = new ObjectInputStream( s.getInputStream( ) );
J_ChatServer.m_output.writeObject("连接成功");
J_ChatServer.m_output.flush( );
J_ChatServer.m_enter.setEnabled( true );
do
{
m = (String) J_ChatServer.m_input.readObject( );
J_ChatServer.mb_displayAppend("客户端: " + m);
this.sleep(1000);
} while(!J_ChatServer.mb_isEndSession( m ));// do-while循环结束
}catch(Exception e){
}
}
}
import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.io.*;
import javax.swing.*;public class J_ChatClient extends JFrame
{
private ObjectInputStream m_input; // 输入流
private ObjectOutputStream m_output; // 输出流
private JTextField m_enter; // 输入区域
private JTextArea m_display; // 显示区域 public J_ChatClient( ) // 在图形界面中添加组件
{
super("聊天程序客户端");
Container c = getContentPane( );
m_enter = new JTextField( );
m_enter.setEnabled( false );
m_enter.addActionListener(new ActionListener( )
{
public void actionPerformed( ActionEvent event )
{ // 向服务器端发送数据
try
{
String s = event.getActionCommand( );
m_output.writeObject( s );
m_output.flush( );
mb_displayAppend( "客户端: " + s );
m_enter.setText( "" ); // 清除输入区域的原有内容
}
catch (Exception e)
{
System.err.println("发生异常:" + e);
e.printStackTrace( );
} // try-catch结构结束
} // 方法actionPerformed结束
} // 实现接口ActionListener的内部类结束
); // addActionListener方法调用结束
c.add( m_enter, BorderLayout.NORTH );
m_display = new JTextArea( );
c.add( new JScrollPane( m_display ), BorderLayout.CENTER );
} // J_ChatClient构造方法结束 public void mb_displayAppend( String s )
{
m_display.append( s + "\n" );
m_display.setCaretPosition( m_display.getText( ).length( ) );
m_enter.requestFocusInWindow( ); // 转移输入焦点到输入区域
} // 方法mb_displayAppend结束 public boolean mb_isEndSession( String m )
{
if (m.equalsIgnoreCase("q"))
return(true);
if (m.equalsIgnoreCase("quit"))
return(true);
if (m.equalsIgnoreCase("exit"))
return(true);
if (m.equalsIgnoreCase("end"))
return(true);
if (m.equalsIgnoreCase("结束"))
return(true);
return(false);
} // 方法mb_isEndSession结束 public void mb_run( String host, int port)
{
try
{
mb_displayAppend("尝试连接");
Socket s = new Socket(host, port);
String m; // 来自服务器端的消息
m_output = new ObjectOutputStream( s.getOutputStream( ) );
m_input = new ObjectInputStream( s.getInputStream( ) );
m_enter.setEnabled( true );
do
{
m = (String) m_input.readObject( );
mb_displayAppend("服务器端: " + m);
} while(!mb_isEndSession( m ));// do-while循环结束
m_output.writeObject("q"); // 通知服务器端退出程序
m_output.flush( );
m_output.close( );
m_input.close( );
s.close( );
System.exit( 0 );
}
catch (Exception e)
{
System.err.println("发生异常:" + e);
e.printStackTrace( );
mb_displayAppend("发生异常");
} // try-catch结构结束
} // 方法mb_run结束 public static void main(String args[ ])
{
J_ChatClient app = new J_ChatClient( );
app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
app.setSize(350, 150);
app.setVisible(true);
if ( args.length == 0 )
app.mb_run("localhost", 5000);
else app.mb_run(args[0], 5000);
} // 方法main结束
} // 类J_ChatClient结束
服务器对外公开的是域名(IP)和端口,
比如sohu的http服务器:www.sohu.com:80。
但这个80端口只是监听端口,
并不用来实际传输数据。而浏览器连接到sohu的http服务器时,
服务器会新建一个socket,用来和浏览器通信。
这个socket的端口就不是 80 了。