socket通信 _ 一个简单的群聊系统
群聊系統(tǒng)要用到通信socket協(xié)議,在java中要用到兩個類java.net.ServerSocket和
Java.net.Socket.ServerSocket用于創(chuàng)建服務器,而Socket用于創(chuàng)建連接。
簡單介紹Socket通信的用法:
首先,我們建立一個簡單的 “服務器—客戶端”一對一的連接來說明如何用socket通信。
1.建立一個服務器ServerSocket? server=new ServerSocket(port);
Port是一個整形數(shù)據(jù),表示端口號,端口的范圍是0~65534,而0~1024端口是系統(tǒng)預留端口,為避免端口被占用我們可以選擇一個較大的數(shù):int port=9900;
2.建立一個鏈接來連接服務器和客戶端。
服務器:Socket socket_server=server.accept();這是一個死等函數(shù),若沒有成功建立連接,則程序不會向下執(zhí)行。
客戶端:Socket socket_client=new Socket(IPaddr,port);IPaddr表示你的網(wǎng)絡IP地址,本系統(tǒng)在本機上運行可以用127.0.0.1代替,否則可以在命令行下輸入ipconfig進行查找。Port為服務器建立的端口號。
3.完成這些以后我們就可以進行服務器和客戶端之間的通信了。
發(fā)消息需要用到java.io.DataInputStream和java.io.DataOutputStream。
?在發(fā)送端:DataOutputStream dout=new DataOutputStream(socket_sever.getoutputString);
?????????????? dout.writeUTF(massage);
?接收端:DateInputStream din=new DateInputStream(socket_client.getInputStream);
?????????????? String accept=din.readUTF();
這樣,服務器端和客戶端就可以進行簡單的通信了。當然,若想時時刻刻都能接收到信息,則必須把接受代碼放入線程中讓其循環(huán)執(zhí)行。
?
群聊系統(tǒng)的設計:
服務器:
功能描述:創(chuàng)建一個服務器,接收來自客戶端的消息,并分發(fā)給每個客戶端。
1.建立服務器
public void BuildServer() {try {int port=9900;server = new ServerSocket(port);System.out.println("創(chuàng)建群聊服務器成功!");InetAddress addr=InetAddress.getLocalHost();System.out.println("本機地址:"+addr); //將網(wǎng)絡地址和端口打印方便客戶端進行連接System.out.println("端口號:"+port);} catch (IOException e) {e.printStackTrace();}}2.創(chuàng)建socket,由于客戶端不止一個,故socket也不只一個,我們可以將Socket=server.accept();循環(huán)執(zhí)行。
@Override //這是重寫Thread類中的run();public void run() {while (true) {try {Socket socket = server.accept();//鏈接建立后,接收客戶端傳來的用戶名信息DataInputStream in = new DataInputStream(socket.getInputStream());String name=in.readUTF();if (name.equals(""))name="匿名用戶";System.out.println(name + "已成功連接!");try {DataOutputStream out = new DataOutputStream(socket.getOutputStream());out.writeUTF(("親愛的"+name+",你已連接到服務器!\n\r"));} catch (IOException e) {e.printStackTrace();}
//這是一個線程類,之后將會創(chuàng)建,用于與客戶端收發(fā)消息GroupThread gt = new GroupThread(socket, list, name);
//list是一個鏈表,存儲每個已存在的連接,其初始化:ArrayList<GroupThread> list = new ArrayList<GroupThread>();list.add(gt);gt.start();} catch (IOException e) {}}
3.主函數(shù)
public class GroupServer extends Thread {/*** @param 群聊服務器*/ServerSocket server;ArrayList<GroupThread> list = new ArrayList<GroupThread>();public void BuildServer() {}@Overridepublic void run() {}public static void main(String[] args) {GroupServer s = new GroupServer();s.BuildServer();s.start();}}?
4.GroupThread類,用于服務器與客戶端的收發(fā)信息,收到來自客戶端的信息后分發(fā)出去。
public class GroupThread extends Thread{Socket socket;String str;String accept;ArrayList<GroupThread> list;private String username;public GroupThread(Socket socket, ArrayList<GroupThread> list,String name){this.socket=socket;this.list=list;this.username=name;}@SuppressWarnings("deprecation") public void run(){while (true) {try {DataInputStream in = new DataInputStream(socket.getInputStream());accept=in.readUTF();if(!accept.equals("")){sendGroup();}} catch (IOException e) {try {//客戶端關閉后斷開連接,將這個鏈接從鏈表中移除,并停止線程System.out.println(username+"已斷開連接!");list.remove(list.indexOf(this));this.stop();socket.close();} catch (IOException e1) {System.out.println("斷開連接出現(xiàn)異常!");}}} }private void sendGroup() {int index=list.indexOf(this);for(int i=0;i<list.size();i++){if(index!=i){list.get(i).Send(accept);}}
public void Send(String str){
?? ??? ?try {
?? ??? ??? ?DataOutputStream out = new DataOutputStream(
?? ??? ??? ??? ??? ?socket.getOutputStream());
?? ??? ??? ?out.writeUTF(str);
?? ??? ?} catch (IOException e) {
?? ??? ??? ?e.printStackTrace();
?? ??? ?}
?? ?} }
?客戶端:
1.登陸界面,提取登錄名(未做驗證),用于顯示群聊過程中的昵稱
public class Login extends JFrame {private static final long serialVersionUID = 1L;private JTextField name = new JTextField(9);private JButton login = new JButton("登錄");public void showUI() {this.setTitle("請輸入你的用戶名");this.setSize(300, 240);this.setDefaultCloseOperation(EXIT_ON_CLOSE);this.setLocationRelativeTo(null);this.setLayout(new FlowLayout());this.setResizable(false);this.add(new JLabel("用戶名:"));this.add(name);Listener listener=new Listener(this,name);name.addKeyListener(listener);this.add(login);login.setFocusable(false);login.addActionListener(listener);this.setVisible(true);}public static void main(String[] args) {new Login().showUI();} }class Listener implements KeyListener,ActionListener{Login login;JTextField jt;private String name;public Listener(Login login,JTextField jt){this.jt=jt;this.login=login;}@Overridepublic void actionPerformed(ActionEvent e) {name=jt.getText();MyChat chat=new MyChat(name);try {chat.runit();} catch (IOException e1) {e1.printStackTrace();}login.setVisible(false);}@Overridepublic void keyTyped(KeyEvent e) {}@Overridepublic void keyPressed(KeyEvent e) {}@Overridepublic void keyReleased(KeyEvent e) {if(e.getKeyCode()==10){name=jt.getText();MyChat chat=new MyChat(name);try {chat.runit();} catch (IOException e1) {e1.printStackTrace();}login.setVisible(false);}}}2.聊天界面
public class MyChat extends Thread {JButton send = new JButton("發(fā)送");JTextField jt = new JTextField(20);JTextArea jta = new JTextArea();DataOutputStream out;Socket socket;String str;byte secret=19;String name;ServerSocket server;JFrame thiss = new JFrame();public MyChat(String name){this.name=name;}public void client() throws IOException {thiss.setSize(400, 300);thiss.setLayout(new BorderLayout());thiss.setDefaultCloseOperation(3);thiss.setLocationRelativeTo(null);JScrollPane js = new JScrollPane(jta);thiss.getContentPane().add(js);thiss.setResizable(false);JPanel south = new JPanel();thiss.add(south, BorderLayout.SOUTH);south.add(jt);send.setFocusable(false);jta.setFocusable(false);jt.addKeyListener(new KeyListener() {@Overridepublic void keyTyped(KeyEvent e) {}@Overridepublic void keyReleased(KeyEvent e) {}@Overridepublic void keyPressed(KeyEvent e) {if (KeyEvent.getKeyText(e.getKeyCode()).equals("Enter")) {str = jt.getText() + "\n\r";jt.setText("");jta.append(name +":" + str);try {out = new DataOutputStream(socket.getOutputStream());out.writeUTF(name +":" + str);} catch (IOException e1) {}};}});send.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent actionEvent) {str = jt.getText() + "\n\r";jt.setText("");jta.append(name+":" + str);try {out = new DataOutputStream(socket.getOutputStream());out.writeUTF((name + ":" + str));} catch (IOException e) {}}});south.add(send);thiss.setVisible(true);}@SuppressWarnings("deprecation")public void run() {while (true) {try {DataInputStream in = new DataInputStream(socket.getInputStream());String accept = in.readUTF();if(!accept.equals(""))jta.append(accept);} catch (IOException e) {try {System.out.println("連接已斷開!");socket.close();this.stop();} catch (IOException e1) {e1.printStackTrace();}} }}public void connect() {try {String addr="127.0.0.1";//本機地址socket = new Socket(addr, 9900);out = new DataOutputStream(socket.getOutputStream());out.writeUTF(name);thiss.setTitle(name);} catch (IOException e) {}}public void runit() throws IOException{this.client();this.connect();this.start();if(name.equals("")){name="匿名";thiss.setTitle("匿名");}} }運行結果:
轉載于:https://www.cnblogs.com/xiao-v/p/4673457.html
總結
以上是生活随笔為你收集整理的socket通信 _ 一个简单的群聊系统的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 硬件断点 DrxHook
- 下一篇: 沙盒文件夹
