Computer >> कंप्यूटर ट्यूटोरियल >  >> प्रोग्रामिंग >> Android

Android में Sockets का उपयोग करके डेटा भेजना और प्राप्त करना (Server/Client)

यह ट्यूटोरियल Android में TCP Sockets का उपयोग करके दो डिवाइस (या एक ही डिवाइस पर दो ऐप्स) के बीच एक साधारण चैट एप्लिकेशन बनाने का प्रदर्शन करता है। इसमें एक Server ऐप और एक Client ऐप शामिल है जो स्थानीय नेटवर्क पर संचार करते हैं।

आर्किटेक्चर अवलोकन

  • Server: निर्दिष्ट पोर्ट (8080) पर सुनता है, कनेक्शन स्वीकार करता है, संदेश पढ़ता/लिखता है
  • Client: Server IP/पोर्ट से कनेक्ट होता है, संदेश भेजता/प्राप्त करता है
  • थ्रेडिंग: नेटवर्क संचालन UI थ्रेड को ब्लॉक न करने के लिए पृष्ठभूमि थ्रेड्स पर चलते हैं
  • runOnUiThread() का उपयोग करके UI अपडेट किए जाते हैं

आवश्यक अनुमतियाँ (दोनों ऐप्स के लिए)

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- Server के लिए स्थानीय IP प्राप्त करने हेतु -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

भाग A: Server ऐप

1. Server Manifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
    package="com.example.socketserver">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="Socket Server"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

2. Server Layout (res/layout/activity_main.xml)

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/tvIP"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="IP: प्रतीक्षा 중..."
        android:textAppearance="@style/TextAppearance.AppCompat.Medium" />

    <TextView
        android:id="@+id/tvPort"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/tvIP"
        android:text="Port: 8080"
        android:textAppearance="@style/TextAppearance.AppCompat.Medium" />

    <TextView
        android:id="@+id/tvConnectionStatus"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/tvPort"
        android:layout_marginTop="8dp"
        android:text="कनेक्शन की प्रतीक्षा..."
        android:textAppearance="@style/TextAppearance.AppCompat.Medium"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/tvMessages"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_above="@id/etMessage"
        android:layout_below="@id/tvConnectionStatus"
        android:layout_marginTop="8dp"
        android:background="#F5F5F5"
        android:padding="12dp"
        android:inputType="textMultiLine"
        android:textAppearance="@style/TextAppearance.AppCompat.Medium" />

    <EditText
        android:id="@+id/etMessage"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_above="@id/btnSend"
        android:layout_marginBottom="8dp"
        android:hint="संदेश दर्ज करें"
        android:inputType="text" />

    <Button
        android:id="@+id/btnSend"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:text="भेजें" />
</RelativeLayout>

3. Server MainActivity.java

package com.example.socketserver;

import android.annotation.SuppressLint;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;

@SuppressLint("SetTextI18n")
public class MainActivity extends AppCompatActivity {

    private static final int SERVER_PORT = 8080;

    private ServerSocket serverSocket;
    private Thread serverThread;
    private PrintWriter output;
    private BufferedReader input;

    private TextView tvIP, tvPort, tvConnectionStatus, tvMessages;
    private EditText etMessage;
    private Button btnSend;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        tvIP = findViewById(R.id.tvIP);
        tvPort = findViewById(R.id.tvPort);
        tvConnectionStatus = findViewById(R.id.tvConnectionStatus);
        tvMessages = findViewById(R.id.tvMessages);
        etMessage = findViewById(R.id.etMessage);
        btnSend = findViewById(R.id.btnSend);

        // स्थानीय IP प्राप्त करें
        try {
            String localIp = getLocalIpAddress();
            tvIP.setText("IP: " + localIp);
            tvPort.setText("Port: " + SERVER_PORT);
        } catch (UnknownHostException e) {
            tvIP.setText("IP: अनुपलब्ध");
            e.printStackTrace();
        }

        // Server थ्रेड प्रारंभ करें
        startServerThread();

        btnSend.setOnClickListener(v -> {
            String msg = etMessage.getText().toString().trim();
            if (!msg.isEmpty() && output != null) {
                new Thread(new SendThread(msg)).start();
            }
        });
    }

    private String getLocalIpAddress() throws UnknownHostException {
        WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(WIFI_SERVICE);
        if (wifiManager == null) throw new UnknownHostException("WifiManager null");
        WifiInfo wifiInfo = wifiManager.getConnectionInfo();
        int ipInt = wifiInfo.getIpAddress();
        if (ipInt == 0) throw new UnknownHostException("IP नहीं मिला");
        byte[] ipBytes = ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN).putInt(ipInt).array();
        return InetAddress.getByAddress(ipBytes).getHostAddress();
    }

    private void startServerThread() {
        serverThread = new Thread(() -> {
            try {
                serverSocket = new ServerSocket(SERVER_PORT);
                runOnUiThread(() -> tvConnectionStatus.setText("कनेक्शन की प्रतीक्षा... (Port " + SERVER_PORT + ")"));

                Socket socket = serverSocket.accept(); // ब्लॉक करता है जब तक क्लाइंट कनेक्ट न हो
                output = new PrintWriter(socket.getOutputStream(), true);
                input = new BufferedReader(new InputStreamReader(socket.getInputStream()));

                runOnUiThread(() -> tvConnectionStatus.setText("कनेक्टेड: " + socket.getInetAddress().getHostAddress()));

                // आने वाले संदेशों को सुनें
                new Thread(new ReceiveThread()).start();

            } catch (IOException e) {
                e.printStackTrace();
                runOnUiThread(() -> tvConnectionStatus.setText("Server त्रुटि: " + e.getMessage()));
            }
        });
        serverThread.start();
    }

    private class ReceiveThread implements Runnable {
        @Override
        public void run() {
            try {
                String msg;
                while ((msg = input.readLine()) != null) {
                    String finalMsg = msg;
                    runOnUiThread(() -> tvMessages.append("Client: " + finalMsg + "\n"));
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                // क्लाइंट डिस्कनेक्ट - नए कनेक्शन के लिए पुनरारंभ
                runOnUiThread(() -> tvConnectionStatus.setText("क्लाइंट डिस्कनेक्ट। प्रतीक्षा..."));
                startServerThread();
            }
        }
    }

    private class SendThread implements Runnable {
        private final String message;
        SendThread(String message) { this.message = message; }
        @Override
        public void run() {
            output.println(message);
            runOnUiThread(() -> {
                tvMessages.append("Server: " + message + "\n");
                etMessage.setText("");
            });
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        try {
            if (serverSocket != null) serverSocket.close();
            if (output != null) output.close();
            if (input != null) input.close();
        } catch (IOException e) { e.printStackTrace(); }
    }
}

भाग B: Client ऐप

1. Client Manifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
    package="com.example.socketclient">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="Socket Client"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

2. Client Layout (res/layout/activity_main.xml)

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    tools:context=".MainActivity">

    <EditText
        android:id="@+id/etIP"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Server IP पता"
        android:inputType="text" />

    <EditText
        android:id="@+id/etPort"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/etIP"
        android:layout_marginTop="8dp"
        android:hint="Port (डिफ़ॉल्ट 8080)"
        android:inputType="number" />

    <Button
        android:id="@+id/btnConnect"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/etPort"
        android:layout_marginTop="16dp"
        android:text="Server से कनेक्ट करें" />

    <TextView
        android:id="@+id/tvMessages"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_above="@id/etMessage"
        android:layout_below="@id/btnConnect"
        android:layout_marginTop="8dp"
        android:background="#F5F5F5"
        android:padding="12dp"
        android:inputType="textMultiLine"
        android:textAppearance="@style/TextAppearance.AppCompat.Medium" />

    <EditText
        android:id="@+id/etMessage"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_above="@id/btnSend"
        android:layout_marginBottom="8dp"
        android:hint="संदेश दर्ज करें"
        android:inputType="text" />

    <Button
        android:id="@+id/btnSend"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:text="भेजें" />
</RelativeLayout>

3. Client MainActivity.java

package com.example.socketclient;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

public class MainActivity extends AppCompatActivity {

    private Thread clientThread;
    private PrintWriter output;
    private BufferedReader input;
    private Socket socket;

    private EditText etIP, etPort, etMessage;
    private TextView tvMessages;
    private Button btnConnect, btnSend;

    private String serverIp = "";
    private int serverPort = 8080;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        etIP = findViewById(R.id.etIP);
        etPort = findViewById(R.id.etPort);
        tvMessages = findViewById(R.id.tvMessages);
        etMessage = findViewById(R.id.etMessage);
        btnConnect = findViewById(R.id.btnConnect);
        btnSend = findViewById(R.id.btnSend);

        btnConnect.setOnClickListener(v -> connectToServer());
        btnSend.setOnClickListener(v -> sendMessage());
    }

    private void connectToServer() {
        serverIp = etIP.getText().toString().trim();
        String portStr = etPort.getText().toString().trim();

        if (serverIp.isEmpty()) {
            etIP.setError("IP दर्ज करें");
            return;
        }
        if (portStr.isEmpty()) {
            serverPort = 8080;
        } else {
            serverPort = Integer.parseInt(portStr);
        }

        tvMessages.setText("कनेक्ट हो रहा है " + serverIp + ":" + serverPort + "...\n");

        clientThread = new Thread(() -> {
            try {
                socket = new Socket(serverIp, serverPort);
                output = new PrintWriter(socket.getOutputStream(), true);
                input = new BufferedReader(new InputStreamReader(socket.getInputStream()));

                runOnUiThread(() -> tvMessages.append("Server से कनेक्टेड!\n"));

                // संदेश प्राप्त करने के लिए थ्रेड प्रारंभ करें
                new Thread(new ReceiveThread()).start();

            } catch (IOException e) {
                e.printStackTrace();
                runOnUiThread(() -> tvMessages.append("कनेक्शन विफल: " + e.getMessage() + "\n"));
            }
        });
        clientThread.start();
    }

    private void sendMessage() {
        String msg = etMessage.getText().toString().trim();
        if (!msg.isEmpty() && output != null) {
            new Thread(() -> {
                output.println(msg);
                runOnUiThread(() -> {
                    tvMessages.append("Client: " + msg + "\n");
                    etMessage.setText("");
                });
            }).start();
        }
    }

    private class ReceiveThread implements Runnable {
        @Override
        public void run() {
            try {
                String msg;
                while ((msg = input.readLine()) != null) {
                    String finalMsg = msg;
                    runOnUiThread(() -> tvMessages.append("Server: " + finalMsg + "\n"));
                }
            } catch (IOException e) {
                e.printStackTrace();
                runOnUiThread(() -> tvMessages.append("कनेक्शन खो गया\n"));
            }
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        try {
            if (socket != null) socket.close();
            if (output != null) output.close();
            if (input != null) input.close();
        } catch (IOException e) { e.printStackTrace(); }
    }
}

चलाने के निर्देश

  1. दोनों ऐप्स को दो Android डिवाइस पर इंस्टॉल करें (या एक डिवाइस + एमुलेटर)।
  2. सुनिश्चित करें कि दोनों एक ही Wi-Fi नेटवर्क पर हैं।
  3. Server ऐप लॉन्च करें - यह अपना IP पता प्रदर्शित करेगा (उदाहरण: 192.168.1.15)।
  4. Client ऐप लॉन्च करें - Server का IP और पोर्ट 8080 दर्ज करें, Connect दबाएं।
  5. "Connected!" दिखाई देने पर, किसी भी तरफ से संदेश टाइप करें और Send दबाएं।

महत्वपूर्ण तकनीकी नोट्स

विषयविवरण
थ्रेडिंगनेटवर्क I/O मुख्य थ्रेड को ब्लॉक करता है → हमेशा पृष्ठभूमि थ्रेड्स का उपयोग करें
UI अपडेटrunOnUiThread() या Handler का उपयोग करना आवश्यक
लाइन-आधारित प्रोटोकॉलPrintWriter.println() + BufferedReader.readLine() सरल टेक्स्ट के लिए
बाइनरी डेटाDataOutputStream/DataInputStream या कस्टम प्रोटोकॉल का उपयोग करें
कनेक्शन जीवनचक्रडिस्कनेक्ट, पुनः कनेक्शन, टाइमआउट को उचित तरीके से संभालें
फायरवॉलसुनिश्चित करें कि नेटवर्क पोर्ट 8080 की अनुमति देता है

उत्पादन विचार

  • OkHttp / Netty / KryoNet जैसे लाइब्रेरी का उपयोग करें मजबूत नेटवर्किंग के लिए
  • TLS/SSL लागू करें सुरक्षित संचार के लिए (SSLSocket)
  • कनेक्शन पूलिंग, पुनः प्रयास तर्क, हार्टबीट जोड़ें
  • सीरियलाइज़ेशन: JSON (Gson/Moshi), Protocol Buffers, या MessagePack का उपयोग करें
  • जीवनचक्र: ViewModel + Coroutine/Flow के साथ नेटवर्क स्थिति प्रबंधित करें

निष्कर्ष

यह उदाहरण Android में कच्चे TCP Socket संचार का प्रदर्शन करता है। जबकि शैक्षिक उद्देश्यों के लिए कार्यात्मक, उत्पादन ऐप्स को उच्च-स्तरीय नेटवर्किंग लाइब्रेरी, उचित त्रुटि प्रबंधन, सुरक्षा और जीवनचक्र प्रबंधन का उपयोग करना चाहिए।

  1. वाईफाई फाइल ट्रांसफर के साथ एंड्रॉइड और PC के बीच फाइल ट्रांसफर करें वाईफाई फाइल ट्रांसफर के साथ एंड्रॉइड और PC के बीच फाइल ट्रांसफर करें

    नेटवर्क पर अपने एंड्रॉइड स्मार्टफोन या टैबलेट के बीच फाइल शेयर करना एक बड़ा टाइमसेवर है। यह लेख आपका मार्गदर्शन करेगा। USB के माध्यम से भी फाइल ट्रांसफर की जा सकती है, लेकिन वायरलेस तरीके से कार्य करना बहुत आसान है। इसे संभव बनाने के लिए एकमात्र पूर्वापेक्षा यह है कि दोनों डिवाइस एक ही नेटवर्क से जु

  1. एंड्रॉइड SMS भेजने/प्राप्त करने के मुद्दों को ठीक करें - त्वरित और विश्वसनीय समाधान एंड्रॉइड SMS भेजने/प्राप्त करने के मुद्दों को ठीक करें - त्वरित और विश्वसनीय समाधान

    आज के युग में, SMS सेवा अप्रचलित और अतीत की एक निशानी की तरह लग सकती है, फिर भी यह टेक्स्ट के माध्यम से संवाद करने का सबसे विश्वसनीय तरीका है। लेकिन किसी भी अन्य प्रकार की तकनीक की तरह, इसकी अपनी समस्याएं हैं जिन्हें हल करने की आवश्यकता है ताकि यह विश्वसनीय और कुशल बना रहे। संदेश भेजने या प्राप्त कर

  1. अपने एंड्रॉइड डेटा उपयोग को ट्रैक और प्रबंधित करें: चरण-दर-चरण गाइड अपने एंड्रॉइड डेटा उपयोग को ट्रैक और प्रबंधित करें: चरण-दर-चरण गाइड

    हर बार जब आपके पास किसी प्रकार का प्रश्न होता है, तो आप अपना स्मार्टफोन अनलॉक करते हैं और उत्तर या समाधान के लिए गूगल की ओर रुख करते हैं। और न केवल यह, हम अपने स्मार्टफोन का उपयोग ऑनलाइन लेनदेन करने, वीडियो कॉल के माध्यम से दोस्तों के साथ संवाद करने, कैब बुक करने, ऑनलाइन खरीदारी करने, या अपने पसंदीद