服务器,使用ServerSocket监听指定的端口,端口可以随意指定(由于1024以下的端口通常属于保留端口,在一些操作系统中不可以随意使用,所以建议使用大于1024的端口),等待客户连接请求,客户连接后,会话产生;在完成会话后,关闭连接。
客户端,使用Java socket通信对网络上某一个服务器的某一个端口发出连接请求,一旦连接成功,打开会话;会话完成后,关闭Socket。客户端不需要指定打开的端口,通常临时的、动态的分配一个1024以上的端口。
首先是服务器端的代码: 由于是实现多机交互所以服务器端接收链接就需要where(true) 接收到链接就调用addclient()方法接收此客户端的名字并创建一个线程保持此客户端的通讯,并且将此客户端放到定义的List<Client>数组中,然后再客户端处理线程类中接收当前客户端的信息,并通过if (c!=this) 判断(this表示发信息的客户端,)将信息发给其他客户端;
源代码已上传我的资源页 http://download.csdn.net/detail/u012373815/8953819
服务器代码如下:
package org.server;
import java.net.*;
import java.util.ArrayList;
import java.util.List;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.io.*;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
/*
* authoryang 2015 7 6
*/
publicclassTCPServer extends JFrame{
publicstatic JTextArea centerTextArea=new JTextArea();
private JPanelsouthPanel,bottompanel;
public List<Client>list =newArrayList<Client>();
Stringname1;
publicvoid setui()throws Exception {
ServerSocket ss = new ServerSocket(5678);//创建一个Socket服务器,监听5566端口
//TODO Auto-generated constructor stub
setTitle("服务器");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(400,400);
setResizable(false); //窗口大小不可调整
setLocationRelativeTo(null);//窗口剧中
//窗口的center部分
centerTextArea.setEditable(false);
centerTextArea.setBackground(new Color(211, 211, 211));
//窗口的SHOTU部分
southPanel =new JPanel(new BorderLayout());
bottompanel=new JPanel(new FlowLayout(FlowLayout.CENTER,5,5));
southPanel.add(bottompanel,BorderLayout.SOUTH);
add(new JScrollPane(centerTextArea),BorderLayout.CENTER);
add(southPanel,BorderLayout.SOUTH);
setVisible(true);
while(true){
Socket s = ss.accept();//利用Socket服务器的accept()方法获取客户端Socket对象。
addclient(s);
System.out.println(list.size());
}
}
//添加客户端
private void addclient(Socket s){
try{
BufferedReader in = new BufferedReader(new InputStreamReader(
s.getInputStream()));
name1=in.readLine();
}catch(IOException e) {
//TODO Auto-generated catch block
e.printStackTrace();
}
Client c = new Client(name1,s);//创建客户端处理线程对象
list.add(c);
Thread t =newThread(c);//创建客户端处理线程
t.start();//启动线程
}
//客户端处理线程类(实现Runnable接口)
class Clientimplements Runnable {
String name;//客户端名字
Socket s = null;//保存客户端Socket对象
BufferedReader in;
PrintWriter out;
Client(String name,Socket s){
this.s = s;
this.name=name;
try{
in =new BufferedReader(new InputStreamReader(
s.getInputStream()));
out =newPrintWriter(s.getOutputStream());
centerTextArea.append("客户端"+name+"连接成功\n");
centerTextArea.setCaretPosition(centerTextArea.getText().length());
}catch(IOException e) {
//TODO Auto-generated catch block
e.printStackTrace();
}
}
publicvoidrun(){
try {
while (true) {
Stringstr = in.readLine();
for(int j=0;j<list.size();j++){
Client c = list.get(j);
if (c!=this) {
System.out.println(str);
c.send(str);
}
}
centerTextArea.append(name+"发出消息:"+str+"\n");
centerTextArea.setCaretPosition(centerTextArea.getText().length());
if (str.equals("end"))
break;
}
try {
s.close();
}catch(IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}catch(IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
publicvoid send(String str) {
out.println("客户端 "+name+"说:"+str);
out.flush();
}
}
publicstaticvoidmain(String[] args)throws Exception{
//利用死循环不停的监听端口
TCPServer tc=new TCPServer();
tc.setui();
}
}
客户端比较简单只需开线程持续接收服务器信息即可 receive.start();
客户端代码如下:
package org.server;
import java.net.*;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public classTCPClient extends JFrame {
private JLabelstateLB;
private JTextAreacenterTextArea , inputTextArea;
private JPanelsouthPanel,bottompanel;
private JTextFieldipTextField,remotePortTF;
private JButtonsendBT,clearBT;
static Socketserver;
Stringname=null ;
PrintWriterout;
BufferedReaderin ;
Thread receive=new Thread( new receiveThread());
public TCPClient()throws Exception{
//此处向服务器发送请求
server = newSocket(InetAddress.getLocalHost(), 5678);
in = newBufferedReader(newInputStreamReader(server.getInputStream()));
out = newPrintWriter(server.getOutputStream());
//建立接收
receive.start();
}
public void setUpUI(){//初始化面板
setTitle("客户端");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(400,400);
setResizable(false); //窗口大小不可调整
setLocationRelativeTo(null);//窗口剧中
stateLB =new JLabel("未链接");
stateLB.setHorizontalAlignment(JLabel.RIGHT);
//窗口的center部分
centerTextArea=new JTextArea();
centerTextArea.setEditable(false);
centerTextArea.setBackground(new Color(211, 211, 211));
//窗口的SHOTU部分
southPanel =new JPanel(new BorderLayout());
inputTextArea=new JTextArea(5,20);
bottompanel=new JPanel(new FlowLayout(FlowLayout.CENTER,5,5));
ipTextField=new JTextField("127.0.0.1",8);
sendBT=new JButton("发送");
clearBT=new JButton("清屏");
bottompanel.add(ipTextField);
bottompanel.add(sendBT);
bottompanel.add(clearBT);
southPanel.add(new JScrollPane(inputTextArea),BorderLayout.CENTER);
southPanel.add(bottompanel,BorderLayout.SOUTH);
add(stateLB,BorderLayout.NORTH);
add(new JScrollPane(centerTextArea),BorderLayout.CENTER);
add(southPanel,BorderLayout.SOUTH);
setVisible(true);
name=JOptionPane.showInputDialog(this,"请输入客户端的名字",JOptionPane.QUESTION_MESSAGE);
setTitle(name);
out.println(name);
out.flush();
stateLB.setText(name+"已链接");
}
public void setListener(){//发送消息
sendBT.addActionListener(new ActionListener() {
@Override
public voidactionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
Stringsendcontent=inputTextArea.getText();
centerTextArea.append(inputTextArea.getText()+"\n");
centerTextArea.setCaretPosition(centerTextArea.getText().length());
inputTextArea.setText("");
try {
out.println(sendcontent);
out.flush();
if (sendcontent.equals("end")) {
server.close();
}
}catch(Exception e2) {
// TODO: handle exception
JOptionPane.showMessageDialog(TCPClient.this,"出错了发送不成功");
e2.printStackTrace();
}
clearBT.addActionListener(new ActionListener() {
@Override
public voidactionPerformed(ActionEvent e) {
centerTextArea.setText("");//清空面板聊天记录
}
});
}
});
}
class receiveThreadimplements Runnable{
//接收线程
@Override
public void run() {
// TODO Auto-generated method stub
try {
while(server!=null)
{
Stringinfo =in.readLine();
centerTextArea.append(info+"\n");
centerTextArea.setCaretPosition(centerTextArea.getText().length());
}
}catch(Exception e) {
// TODO: handle exception
}
}
}
public static void main(String[] args)throws Exception {
TCPClientc=newTCPClient();
c.setUpUI();
c.setListener();
}
}