Socket客户端-服务器(C-S)通信实验
1.需求分析
设计程序,分别构建通信的两端:服务器端和客户端应⽤程序,套接字类型为⾯向连接的Socket,⾃⼰构建双⽅的应答模式,实现双⽅的数据的发送和接收(S发给C,C发给S)。
服务端程序能响应单个或任意多个客户端连接请求;服务端能向单个客户发送消息,⽀持发消息给所有客户端;通信的双⽅具备异常响应功能,包括对⽅异常退出的处理。如果客户端退出,服务器有响应;反之亦然。
编程实现的思路:在服务器端,⾸先要启动⼀条线程⽤于监听某个指定端⼝(⽐如:8000),并且还要再开⼀条线程⽤于接收消息,客户端尝试连接该端⼝(8000),如果成功连接则会返回⼀个Socket类的实例对象(Socket socket = serversocket.accept() ,很显然服务器端便应该保存有⼀个客户列表(⽐如可以⽤:ArrayList),使得服务器可以发消息给某个指定的客户端。⽽客户端在连接服务器之后也应该启动⼀条线程⽤于接收消息。当某个客户端进来时,便发送Login消息给服务器,服务器将此消息⼴播发给当前在线的所有⽤户,当某个客户端退出时,发送Logout消息给服务器,服务器将此消息⼴播发给当前在线的所有⽤户,当客户端之间进⾏通信时,会发送Talk消息给服务器,服务器再将此消息转发给指定的客户端,也就是所有的通信都是通过服务器进⾏转发的。
1. 创建JAVA应⽤程序⼯程
如图
2. 1创建UI视图类
2.1.1建⽴ClientView类
创建成功:
public class ClientView extends JFrame implements{
}
2.1.2实现处理交互事件的接⼝
让ClientView类实现ActionListener, KeyListener接⼝。并使⽤IDE⾃动⽣成接⼝中的⽅法。
public class ClientView extends JFrame implements ActionListener, KeyListener{
@Override
public void keyPressed(KeyEvent e){
// TODO Auto-generated method stub
}
@Override
public void keyReleased(KeyEvent e){
// TODO Auto-generated method stub
}
@Override
public void keyTyped(KeyEvent e){
// TODO Auto-generated method stub
}
@Override
public void actionPerformed(ActionEvent e){
// TODO Auto-generated method stub
}socket编程聊天室基本流程
}
keyPressed():处理键盘按下事件
actionPerformed():处理⿏标点击事件
2.1.3UI元素初始化
⾸先,在类中添加如下成员变量:
private JTextArea taChatList;// 聊天内容区
private JTextField tfMessage;// 聊天输⼊框
private JTextField tfName;// ⽤户名输⼊框
private JButton btnSend;// 发送按钮
private JLabel labelNick;
private JPanel jp1, jp2;
private JScrollPane scrollPane;
private JLabel labelHost;
private JLabel labelPort;
private JTextField tfHost;// 服务器地址输⼊框
private JTextField tfPort;// 服务器端⼝输⼊框
private JButton btnConnect;// 连接/断开服务器按钮
接下来,编写⼀个⽤户界⾯初始化函数initView(),对各个UI元素对象分配存储空间,并按照设计要求添加到视图中。代码如下:
private void initView(){
taChatList =new JTextArea(20,20);
taChatList.setEditable(false);
scrollPane =new JScrollPane(taChatList);
tfMessage =new JTextField(15);
btnSend =new JButton("发送");
jp1 =new JPanel();
labelHost =new JLabel("主机地址");
tfHost =new JTextField(15);
tfHost.setText("localhost");
labelPort =new JLabel("端⼝号");
tfPort =new JTextField(4);
tfPort.setText("8765");
btnConnect =new JButton("连接");
jp1.add(labelHost);
jp1.add(tfHost);
jp1.add(labelPort);
jp1.add(tfPort);
jp1.add(btnConnect);
labelNick =new JLabel("昵称:");
tfName =new JTextField(8);
jp2 =new JPanel();
jp2.add(labelNick);
jp2.add(tfName);
tfName.setText("⽤户0");
jp1.setLayout(new FlowLayout(FlowLayout.CENTER));
jp2.add(tfMessage);
jp2.add(btnSend);
jp2.setLayout(new FlowLayout(FlowLayout.CENTER));
add(jp1, BorderLayout.NORTH);
add(scrollPane, BorderLayout.CENTER);
add(jp2, BorderLayout.SOUTH);
setTitle("聊天室");
setSize(500,500);
setLocation(450,150);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
// 当光标定位在聊天输⼊框时监听回车键按下事件
tfMessage.addKeyListener(this);
// 为发送按钮增加⿏标点击事件监听
btnSend.addActionListener(this);
// 为连接按钮增加⿏标点击事件监听
btnConnect.addActionListener(this);
/
/ 当窗⼝关闭时触发
addWindowListener(new WindowAdapter(){// 窗⼝关闭后断开连接
@Override
public void windowClosing(WindowEvent e){
}
});
}
到keyPressed()⽅法,添加对按下回车键事件的处理:
@Override
public void keyPressed(KeyEvent e){
// TODO Auto-generated method stub
KeyCode()== KeyEvent.VK_ENTER){
// 发送聊天消息
}
}
到actionPerformed()⽅法,添加对两个按钮的响应:
@Override
public void actionPerformed(ActionEvent e){
// TODO Auto-generated method stub
Source()== btnSend){
// 响应发送按钮
}else Source()== btnConnect){
/
/ 响应连接/断开按钮
}
}
最后,为ClientView创建⼀个构造⽅法,并且在构造⽅法中调⽤initView()⽅法对⽤户界⾯进⾏创建:
public ClientView(){
initView();
}
2.1.4运⾏程序查看主窗⼝
在ClientView类的末尾增加主函数作为程序运⾏的⼊⼝:
public static void main(String[] args){
ClientView view =new ClientView();
}
运⾏结果如图:
2.2 编写⽹络服务模块
2.2.1 创建Networkservice类
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论