// 在服务器上部署的程序
package wang.socket.Server;
// java 提供的网络功能包
import java.net.*;
// java 提供的输入输出的功能包
import java.io.*;
// 使用线程来处理Socket请求
public class ThreadServer {
public static void main(String[] args) throws Exception {
// 监听服务
ServerSocket server;
// 启动一个监听服务器
server = new ServerSocket(9999);
System.out.println("---------> 一个Socket监听服务器启动:" + server.toString());
while (true) {//循环地响应客户端的请求
//获得客户端连接,也就是要建立一个Socket套接字,由于没有使用线程,多个客户端连接会排队
// ServerSocket的接收套接字的方法是采用队列并等待的方式,如果没有呼入连接,则程序在等待,不向下执行.
Socket client = server.accept();
// 创建线程,让线程去应答客户的请求
new ServerThread(client).start();
}
}
}
// 以线程处理客户的请求
class ServerThread extends Thread {
//主程序的main函数会把创建的Socket作为参数传递给线程执行.
private Socket sk;
public ServerThread(Socket s) {
this.sk = s;
}
@Override
public void run() {
System.out.println("(一个客户请求:)" + this.sk.toString());
// 缓冲区读取器
BufferedReader in;
// 响应器
PrintWriter out;
// 取得客户端的计算机的IP地址
String remoteIP = this.sk.getInetAddress().getHostAddress();
// 取得客户端用于通讯的端口号
int remotePort = this.sk.getLocalPort();
// 在服务器的监控台上显示客户端接入的信息
System.out.println("一个客户端正在连入, IP:" + remoteIP + ", 端口: " + remotePort);
//获得 client 端的输入输出流,为进行交互做准备
try {
in = new BufferedReader(new InputStreamReader(this.sk.getInputStream()));
//获得输出
out = new PrintWriter(this.sk.getOutputStream(), true);
//获得 client 端发送的数据,要注意的是客户端从一个套接字里有可能发送多行的数据。
String content;
// 只有比较明显地给出一个数据流终结的方式才好
while (!(content = in.readLine()).equals("taxend")) {
System.out.println("客户端发来的消息: " + content);
out.println(content);
// 向 client 端发送响应数据
}
//关闭各个流
// out.flush(); 清缓冲区
out.close();
in.close();
// 一次通讯结束,可以关闭socket
this.sk.close();
} catch (Exception ex) {
// ex.printStackTrace();
System.out.println("客户挂断了.........");
}
}
}
// 在客户端部署的程序
package wang.socket.Client;
import java.net.*;
import java.io.*;
/**
*
* @author WangQingda
*/
public class AWTClient extends javax.swing.JFrame {
/** Creates new form AWTClient */
public AWTClient() {
initComponents();
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
jLabel1 = new javax.swing.JLabel();
jLabel2 = new javax.swing.JLabel();
theServerIP = new javax.swing.JTextField();
jScrollPane1 = new javax.swing.JScrollPane();
theContent = new javax.swing.JTextArea();
jButton1 = new javax.swing.JButton();
jScrollPane2 = new javax.swing.JScrollPane();
theServerOutPut = new javax.swing.JTextArea();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setTitle("测试Socket数据流");
jLabel1.setText("请输入服务器地址:");
jLabel2.setText("输入需要提交数据流:");
theServerIP.setText("127.0.0.1");
theContent.setColumns(20);
theContent.setRows(5);
jScrollPane1.setViewportView(theContent);
jButton1.setLabel("提交");
jButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton1ActionPerformed(evt);
}
});
theServerOutPut.setColumns(20);
theServerOutPut.setRows(5);
jScrollPane2.setViewportView(theServerOutPut);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
.addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
.addContainerGap()
.addComponent(jScrollPane2))
.addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
.addGap(31, 31, 31)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jLabel2)
.addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 88, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 317, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(layout.createSequentialGroup()
.addComponent(jLabel1)
.addGap(18, 18, 18)
.addComponent(theServerIP, javax.swing.GroupLayout.PREFERRED_SIZE, 167, javax.swing.GroupLayout.PREFERRED_SIZE)))))
.addContainerGap(31, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(41, 41, 41)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel1)
.addComponent(theServerIP, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addGroup(layout.createSequentialGroup()
.addGap(34, 34, 34)
.addComponent(jLabel2)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jButton1))
.addGroup(layout.createSequentialGroup()
.addGap(18, 18, 18)
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(13, Short.MAX_VALUE))
);
pack();
}// </editor-fold>
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
try {
//连接 server 端
System.out.println("连接服务器 ...");
Socket client = new Socket(this.theServerIP.getText(), 9999);
//显示已连接
System.out.println("成功接入服务器.");
System.out.println();
//为发送数据做准备
System.out.println("请输入:");
// 注意字符串要以字符流的形式读入。
BufferedReader in = new BufferedReader(new StringReader(this.theContent.getText()));
// 流的输出可以从socket的输出流得到。
PrintWriter out = new PrintWriter(client.getOutputStream(), true);
// 向 server 发送数据
String outTxt;
while ((outTxt = in.readLine()) != null) {
out.println(outTxt);
System.out.println("向服务器发送:"+outTxt);
}
out.flush();
this.theServerOutPut.append("数据已经成功向服务器发送");
//接收来自 server 的响应数据
in = new BufferedReader(new InputStreamReader(client.getInputStream()));
String inTxt;
while ((inTxt = in.readLine()) != null) {
this.theServerOutPut.append(inTxt);
}
// 关闭各个流
in.close();
out.close();
// 客户端退出
client.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new AWTClient().setVisible(true);
}
});
}
// Variables declaration - do not modify
private javax.swing.JButton jButton1;
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel2;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JScrollPane jScrollPane2;
private javax.swing.JTextArea theContent;
private javax.swing.JTextField theServerIP;
private javax.swing.JTextArea theServerOutPut;
// End of variables declaration
}
追问这个程序我基本看了一下,也运行了,除了按了提交按钮后客户端主线程有死循环外,整个程序也没有完成多个客户端之间的P2P通信,在你这个程序中只完成了客户端和服务器之间的通信,我之所以说模拟QQ是指只希望服务器端只做中转,而非直接与客户端通信,所以你的回答我不能采纳,谢谢