请教大家一个socket编程的问题,如果客户端和服务端连接上了,我想要实现的是,客户端对服务端的发送,命令数据和实际数据分离,该如何实现了?
[b]问题补充:[/b]
这样不行吧,万一,用户输入了"%"号+命令,怎么办?,有没办法建立2个socket并且实现命令和数据socket绑定··
[b]问题补充:[/b]
请问下,怎么实现个Socket命令和数据邦定
可以给段sample吗~~谢谢了~~
import java.net.*;
import java.io.*;
import java.sql.*;
import java.util.*;
public class Server{
public static void main(String args[]){
try {
HashMap hm= new HashMap();
//服务器监听
ServerSocket ss=new ServerSocket(8000);
//启动服务线程
while(true){
System.out.println ("服务器正在8000端口监听...");
Socket s=ss.accept();
MyService t=new MyService();
t.setSocket(s);
t.setHashMap(hm);
t.start();
}
}
catch (Exception ex) {
ex.printStackTrace();
}
}
}
class MyService extends Thread{
private Socket s;
private HashMap hm;
public void setHashMap(HashMap hm){
this.hm = hm;
}
public void setSocket(Socket s){
this.s = s;
}
public void run(){
try {
//接受用户名和密码
InputStream is=s.getInputStream();
InputStreamReader isr=new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String uandp = br.readLine();
System.out.println ("接受的用户名和密码为:"+uandp) ;
//拆分
String u=uandp.split("%")[0];
String p=uandp.split("%")[1];
//到数据库确认信息
Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
Connection cn=DriverManager.getConnection("jdbc:microsoft:sqlserver://127.0.0.1:1433;databasename=zky","sa","");
PreparedStatement ps=cn.prepareStatement("select * from username where username=? and password=?");
ps.setString(1,u);
ps.setString(2,p);
ResultSet rs = ps.executeQuery();
OutputStream os=s.getOutputStream();
OutputStreamWriter osw=new OutputStreamWriter(os);
PrintWriter pw=new PrintWriter(osw,true);
if(rs.next()){
pw.println("ok");
pw.flush() ;
//hm.put(u,s);
//将自己的名字发送给其他的人
for(Socket ts : hm.values()){
OutputStream tos=ts.getOutputStream();
OutputStreamWriter tosw=new OutputStreamWriter(tos);
PrintWriter tpw=new PrintWriter(osw,true);
tpw.println("user%"+u);
tpw.flush() ;
}
//将其他人的名字发给自己
for(String tu : hm.keySet()){
pw.println("user%"+tu);
pw.flush() ;
}
//将用户名和Socket存入HashMap
hm.put(u,s);
System.out.println ("存入HashMap中的信息为:"+hm);
//不断接受客户端信息
while(true){
//拆分名字和信息
String message = br.readLine();
String user = message.split("%")[0];
String mess = message.split("%")[1];
//得到Socket
Socket ts = hm.get(user);
OutputStream tos=ts.getOutputStream();
OutputStreamWriter tosw=new OutputStreamWriter(tos);
PrintWriter tpw = new PrintWriter(tosw,true);
//发送信息
tpw.println("mess%"+u+"对"+user+"说:"+mess);
tpw.flush() ;
System.out.println ("messge是:"+message);
}
}else {
pw.println("error");
}
}
catch (Exception ex) {
ex.printStackTrace();
}
}
}
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.net.*;
import java.io.*;
public class Login extends JFrame implements ActionListener{
JTextField t_username=new JTextField();
JPasswordField t_password=new JPasswordField();
Login(){
//设置窗体属性
this.setSize(250,150);
this.setTitle("登陆窗口");
this.setResizable(false);
int width=(int)(Toolkit.getDefaultToolkit().getScreenSize().getWidth());
int height=(int)(Toolkit.getDefaultToolkit().getScreenSize().getHeight());
this.setLocation((width-250)/2,(height-150)/2);
//new一堆属性
JLabel l_username=new JLabel("用户名",SwingConstants.CENTER);
JLabel l_password=new JLabel("密码",SwingConstants.CENTER);
JButton b_login=new JButton("登陆");
JButton b_reg=new JButton("注册");
JButton b_cancel=new JButton("取消");
//注册事件
b_login.addActionListener(this);
b_reg.addActionListener(this);
b_cancel.addActionListener(this);
//设置输入面板
JPanel p_input=new JPanel();
p_input.setLayout(new GridLayout(2,2));
p_input.add(l_username);
p_input.add(t_username);
p_input.add(l_password);
p_input.add(t_password);
//设置按钮面板
JPanel p_button=new JPanel();
p_button.setLayout(new FlowLayout());
p_button.add(b_login);
p_button.add(b_reg);
p_button.add(b_cancel);
//设置窗体面板
this.setLayout(new BorderLayout());
this.add(p_input,BorderLayout.CENTER);
this.add(p_button,BorderLayout.SOUTH);
}
public static void main(String args[]){
JFrame.setDefaultLookAndFeelDecorated(true);
Login l=new Login();
l.setVisible(true);
}
/**
* Method actionPerformed
*
*
* @param e
*
*/
public void actionPerformed(ActionEvent e) {
if(e.getActionCommand().equals("登陆")){
try {
Socket s=new Socket("127.0.0.1",8000);
//发送用户名和密码
OutputStream os=s.getOutputStream();
OutputStreamWriter osw=new OutputStreamWriter(os);
PrintWriter pw=new PrintWriter(osw,true);
pw.println(t_username.getText()+"%"+t_password.getText());
//接受服务器的返回信息
InputStream is=s.getInputStream();
InputStreamReader isr=new InputStreamReader(is);
BufferedReader br=new BufferedReader(isr);
String yorn=br.readLine();
//弹出主窗体
if(yorn.equals("ok")){
Chat c = new Chat(t_username.getText());
c.setSocket(s);
c.setVisible(true);
this.setVisible(false);
}
}
catch (Exception ex) {
ex.printStackTrace();
}
}
if(e.getActionCommand().equals("注册")){
}
if(e.getActionCommand().equals("取消")){
}
}
}
import java.awt.*;
import javax.swing.*;
import java.net.*;
import java.io.*;
import java.awt.event.*;
public class Chat extends JFrame implements ActionListener , Runnable{
JTextField tt=new JTextField();
JTextArea area=new JTextArea();
JComboBox user=new JComboBox();
private Socket s;
public void setSocket(Socket s){
this.s=s;
}
Chat(String username){
//设置窗体属性
this.setSize(400,500);
this.setTitle(username+"的聊天窗口");
this.setResizable(false);
int width=(int)(Toolkit.getDefaultToolkit().getScreenSize().getWidth());
int height=(int)(Toolkit.getDefaultToolkit().getScreenSize().getHeight());
this.setLocation((width-400)/2,(height-500)/2);
//new一堆属性
JButton send=new JButton("发送");
JScrollPane sp=new JScrollPane(area);
//注册事件
send.addActionListener(this);
//设置按钮面板
JPanel p_button=new JPanel();
p_button.setLayout(new GridLayout(1,2));
p_button.add(user);
p_button.add(send);
//设置上半部面板
JPanel p_xiao=new JPanel();
p_xiao.setLayout(new GridLayout(2,1));
p_xiao.add(tt);
p_xiao.add(p_button);
//读聊天记录
try {
File inf=new File("d:/聊天记录.txt");
FileReader fr=new FileReader(inf);
BufferedReader br=new BufferedReader(fr);
while(br.ready()){
area.append(br.readLine()+"\n");
//System.out.println (br.readLine());
}
}
catch (Exception ex) {
ex.printStackTrace();
}
//设置窗体面板
this.setLayout(new BorderLayout());
this.add(p_xiao,BorderLayout.NORTH);
this.add(sp,BorderLayout.CENTER);
Thread t=new Thread(this);
t.start();
}
/**
* Method actionPerformed
*
*
* @param e
*
*/
public void actionPerformed(ActionEvent e) {
if(e.getActionCommand().equals("发送")){
//tt---->area
area.append(tt.getText()+"\n");
//tt---->file
try {
File outf=new File("d:/聊天记录.txt");
FileWriter fw=new FileWriter(outf,true);
PrintWriter pw=new PrintWriter(fw,true);
pw.println(tt.getText());
pw.close();
}
catch (Exception ex) {
ex.printStackTrace();
}
//tt------->server
try {
OutputStream os=s.getOutputStream();
OutputStreamWriter osw=new OutputStreamWriter(os);
PrintWriter pw = new PrintWriter(osw,true);
pw.println(user.getSelectedItem()+"%"+tt.getText());
}
catch (Exception ex) {
ex.printStackTrace();
}
tt.setText("");
}
}
public void run(){
try {
Thread.sleep(2);
System.out.println ("socket是:"+s) ;
InputStream is=s.getInputStream();
InputStreamReader isr=new InputStreamReader(is);
BufferedReader br=new BufferedReader(isr);
while(true){
String message = br.readLine();
System.out.println (message);
String to=message.split("%")[0];
String mess=message.split("%")[1];
if(to.equals("user")){
user.addItem(mess);
System.out.println ("接受的用户名是:"+mess) ;
}
if(to.equals("mess")){
area.append(message+"\n") ;
System.out.println ("客户端接受到的聊天信息是:"+message) ;
}
}
}
catch (Exception ex) {
ex.printStackTrace();
}
}
}
自己慢慢看
你可以通过标志性的字符来分离:如"%"号等,获得这些数据后,通过这些标志性的字符来分离,从而实现命令与数据分离
你可以用一个或多个阿,这个要看你自己怎么设置在,例如“%%%----%%%”等等,或者其他很少用到的字符。
你可以通过进程机制来实现多个Socket命令和数据邦定,这些Socket都是共用一个服务器的ServerSocket