繁体   English   中英

从客户端向服务器发送消息

[英]Send message from client to server

我已经与使用android studio制作的Android客户端和使用Java制作的服务器进行了聊天。

如何将消息从客户端发送到服务器? 并从服务器向所有客户端广播消息?

例:

  1. 客户端#1发送:您好
  2. 服务器收到:你好
  3. 服务器将消息(Hello)发送给所有其他客户端。

主服务器:

package server1;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.*;


public class Server1 {

 public static void main(String[] args) throws IOException {

  Socket newsock = null;
    int nreq = 1;
    try
    {
        ServerSocket sock = new ServerSocket (3000);
        for (;;)
        {
            newsock = sock.accept();
            System.out.println("Creating thread ...");
            Thread t = new ThreadHandler(newsock,nreq);
            t.start();

        }
    }
    catch (Exception e)
    {
        System.out.println("IO error " + e);
    }
    System.out.println("End!");

    BufferedReader in=new BufferedReader(new InputStreamReader(newsock.getInputStream()));
    PrintWriter out=new PrintWriter(newsock.getOutputStream(),true);

}

}

ThreadHandler(服务器):

package server1;
import java.io.*;
import java.net.*;

class ThreadHandler extends Thread {
Socket newsock;
int n;

ThreadHandler(Socket s, int v) {
    newsock = s;
    n = v;
}


public void run() {
    try {

        PrintWriter outp = new PrintWriter(newsock.getOutputStream(), true);
        BufferedReader inp = new BufferedReader(new InputStreamReader(
                newsock.getInputStream()));

        outp.println("Hello :: enter QUIT to exit \n");
        boolean more_data = true;
        String line;

        while (more_data) {
            line = inp.readLine();
            System.out.println("Message '" + line + "' echoed back to 
 client.");
            if (line == null) {
                System.out.println("line = null");
                more_data = false;
            } else {
                outp.println("From server: " + line + ". \n");
                if (line.trim().equals("QUIT"))
                    more_data = false;
            }
        }
        newsock.close();
        System.out.println("Disconnected from client number: " + n);
    } catch (Exception e) {
        System.out.println("IO error " + e);
    }

}
}

Android MainActivity.java:

package com.example.mirko.chatclient;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;

public class MainActivity extends AppCompatActivity {

    TextView chatzone;
    EditText msg;
    Button btninvio;
    Socket socket;
    PrintWriter out;
    BufferedReader in;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    final int PORTA=3000;
    final String IP = "192.168.1.2";

    try {
        socket=new Socket(IP,PORTA);
    } catch (IOException e) {
        e.printStackTrace();
    }
    //si connette al server

    chatzone= findViewById(R.id.chatzone);
    msg= findViewById(R.id.msg);
    btninvio=findViewById(R.id.btninvia);
    //si dichiara i componenti


    try {
        in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    } catch (IOException e) {
        e.printStackTrace();
    }
    try {
        out= new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
    } catch (IOException e) {
        e.printStackTrace();
    }

}
public void premuto(View v)
{
    String messaggio=msg.getText().toString();
    out.println(messaggio);


}


}

Android xml:

    <?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.mirko.chatclient.MainActivity">

<TextView
    android:id="@+id/chatzone"
    android:layout_width="343dp"
    android:layout_height="309dp"
    android:layout_marginEnd="24dp"
    android:layout_marginStart="24dp"
    android:layout_marginTop="16dp"
    android:text="@string/chatzone"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

<Button
    android:id="@+id/btninvia"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginBottom="32dp"
    android:layout_marginEnd="148dp"
    android:onClick="premuto"
    android:text="@string/invia"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent" />

<EditText
    android:id="@+id/msg"
    android:layout_width="344dp"
    android:layout_height="43dp"
    android:layout_marginBottom="32dp"
    android:layout_marginEnd="24dp"
    android:layout_marginStart="24dp"
    android:layout_marginTop="32dp"
    android:ems="10"
    android:inputType="text"
    android:labelFor="@+id/msg"
    android:text="@string/msg"
    app:layout_constraintBottom_toTopOf="@+id/btninvia"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/chatzone" />

您的服务器代码有逻辑问题。 您为每个客户端连接启动一个新线程。 您的ThreadHandler可以读写该单个客户端。 它没有任何其他可能的客户端的信息。

您的服务器必须有一个“主线程”来处理客户端之间的通信。 您的客户端线程每个都应具有一个用于出站消息的FIFO队列。 服务器需要保留传入消息的中央FIFO队列和每个客户端出站消息队列的指针列表。 客户端线程从其套接字读取消息,然后将其放入中央传入队列。 “主线程”从该队列中读取消息,并将其放入每个客户端线程的出站队列中。 所有这些都必须正确同步。

因此,您的客户端线程从套接字读取消息并将其放入公共队列,然后从其自己的出站队列读取消息并将其写入套接字。 主线程从公共传入队列中读取消息,并将消息写入单个客户端线程的出站队列。

通常,您要解决的问题非常困难。 除非这对您来说是纯粹的学习经验,并且可以失败,否则您不应该自己构建。 使用现成的东西,例如先前建议的东西或https://github.com/tinode/chat

此外,Java并不是此类服务器端应用程序的最佳语言。 大多数此类应用程序都是用Erlang( https://github.com/esl/MongooseIM )和Go编写的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM