歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Socket編程學習

Socket的服務器端需要在某個端口上開啟服務器類型的Socket,即java.net.ServerSocket,通過它的accpet方法等待並接收客戶端的請求,返回的是一個java.net.Socket對象,如果一直沒有客戶端的請求,那麼accept方法將會一直等待。

Socket客戶端根據服務器的IP地址(域名)和端口號創建一個Socket對象,連接服務器。

服務器端和客戶端都持有一個Socket對象,服務器端的Socket從服務器端指向客戶端,而客戶端的Socket從客戶端指向服務器端,就像在服務器端和客戶端建立了兩條單向的管道。

通過Socket類提供的getOutputStream方法獲得Socket的輸出流,getInputStream方法獲得Socket的輸入流。

實例如下:

package book.net.simplesocket;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;

/**
 *一個簡單的Socket服務器,能接收客戶端的請求,並將請求返回給客戶端
 */
public class SimpleServer {
    ServerSocket serverSkt = null;//服務器端偵聽的Socket
    Socket clinetSkt = null;//客戶端
    BufferedReader in = null;//客戶端輸入流
    PrintStream out = null;//客戶端輸出流
    //構造方法
    public SimpleServer(int port){
        System.out.println("服務器代理正在監聽,端口:" + port);
        try {
            serverSkt = new ServerSocket(port);//創建堅挺Socket
        } catch (IOException e) {
            System.out.println("監聽端口" + port + "失敗");
        }
        try {
            clinetSkt = serverSkt.accept();//接收連接請求
        } catch (IOException e) {
            System.out.println("連接失敗");
        }
        try {
            in = new BufferedReader(new InputStreamReader(clinetSkt.getInputStream()));
            out = new PrintStream(clinetSkt.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    //收到客戶端請求
    public String getRequest(){
        String frmClt = null;
        try {
            frmClt = in.readLine();//從客戶端的輸入流中讀取一行數據
            System.out.println("Server收到請求:" + frmClt);
        } catch (IOException e) {
            System.out.println("無法讀取端口。。。。");
            System.exit(0);
        }
        return frmClt;
    }
    //發送響應給客戶端
    public void sendResponse(String response){
        out.println(response);//往客戶端輸出流中寫數據
        System.out.println("Server響應請求:" + response);
    }
    public static void main(String[] args) {
        SimpleServer sa = new SimpleServer(8888);//啟動服務器
        while(true){
            //讀取客戶端的輸入並返回給客戶端
            sa.sendResponse(sa.getRequest());
        }
    }
}

package book.net.simplesocket;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;

public class SimpleClient {
    //客戶端輸入/輸出流
    PrintStream out;
    BufferedReader in;
    //構造方法
    public SimpleClient(String serverName,int port){
        //根據服務器名和端口號,連接服務器
        try {
            Socket clientSocket = new Socket(serverName,port);
            out = new PrintStream(clientSocket.getOutputStream());
            in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
        } catch (Exception e) {
            System.out.println("無法連接服務器!");
        }
    }
    //發送請求
    public void sendRequest(String request){
        out.println(request);
        System.out.println("Client發送請求:" + request);
    }
    public String getResponse(){
        String str = new String();
        try {
            str = in.readLine();
            System.out.println("Client收到Server返回:" + str);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return str;
    }
}

package book.net.simplesocket;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

public class ClientFrame extends JFrame implements ActionListener{
    JButton sendButton;//“發送”按鈕
    JTextField inputField;//發送內容的輸入框
    JTextArea outputArea;//服務器返回內容的文本域
    SimpleClient client;//客戶端Socket對象
    //在構造函數中完成圖形界面的初始化
    public ClientFrame(){
        JLabel label1 = new JLabel("輸入:");
        inputField = new JTextField(20);
        JPanel panel1 = new JPanel();
        panel1.add(label1);
        panel1.add(inputField);
       
        JLabel label2 = new JLabel("服務器返回:");
        outputArea = new JTextArea(6,20);
        JScrollPane crollPane = new JScrollPane(outputArea);
        JPanel panel2 = new JPanel();
        panel2.setLayout(new BorderLayout());
        panel2.add(label2,BorderLayout.NORTH);
        panel2.add(crollPane,BorderLayout.CENTER);
       
        sendButton = new JButton("發  送");
        sendButton.addActionListener(this);
       
        JPanel panel = new JPanel();
        panel.setLayout(new BorderLayout());
        panel.add(panel1, BorderLayout.NORTH);
        panel.add(sendButton,BorderLayout.CENTER);
        panel.add(panel2, BorderLayout.PAGE_END);
       
        setTitle("Socket客戶端");
        this.getContentPane().add(panel);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
    @Override
    public void actionPerformed(ActionEvent ae) {
        //判斷事件源控價是否是“發送”按鈕
        if(ae.getSource() == sendButton){
            client.sendRequest(inputField.getText());//發送文本框中的文本
            //接收服務器端回應並寫入文本域
            outputArea.append(client.getResponse() + "\n");
        }
    }
    public static void main(String[] args) {
        ClientFrame frame = new ClientFrame();
        frame.pack();
        //連接服務器端
        frame.client = new SimpleClient("127.0.0.1",8888);
        frame.setVisible(true);
    }

}

分析:

1.SimpleServer類

該類實現了Socket服務器端。

(1)在構造方法中創建一個ServerSocket對象,偵聽指定的端口,然後調用accept方法等待並接收客戶端的請求,收到連接請求後,獲取Socket的輸入/輸出流的引用。

(2)getRequest方法從Socket的輸入流中讀取來自客戶端的請求消息,sendResponse方法將響應消息發送到Socket的輸出流,即客戶端。

(3)在main方法中,新建一個SimpleServer對象,然後不斷地接收客戶端的請求,將收到的請求按照原樣返回給客戶端。

2.SimpleClient類

該類實現了Socket客戶端。

(1)在構造方法中,根據服務器端的IP地址和端口號創建一個Socket對象,此時便連接到服務器端,獲得Socket的輸入/輸出流的引用。

(2)sendRequest方法向Socket的輸出流中發送請求,即向服務器端發送請求:getResponse方法從Socket的輸入流中讀取信息,即獲取服務器端的響應消息。

3.ClientFrame類

該類實現了客戶端的圖形化。

在文本框中輸入請求消息,單擊“發送”按鈕,調用SimpleClient的sendRequest方法,將文本框中的消息發送給服務器端,然後調用SimpleClient的getResponse方法獲得服務器端的響應消息,並顯示在文本域中。

Copyright © Linux教程網 All Rights Reserved