java子线程向主线程发消息,Java:多线程聊天服务器仅向1个客户端发送消息

After getting a lot of help in my previous questions finally I attempted to make a multiple client. Its not working properly and I will try to explain the basics of code before posting whole code.

Basic Classes:

ChatServer.Java -- Starts a ServerSocket. Waits for user to connect. Adds user to ArrayList. Starts a new thread for every user. The thread it starts will wait for inputs to come in from client and loop over list of clients and send the message to all.

CharServer2.Java : Just a GUI interface to start up Chat Server

Chat1: Connects to socket. send and receives messages. Both actions on different threads.

ChatClient.Java : GUI for Chat1 trigger.

Now if I start the server and connect one client it works fine. If I add two clients things get rough :( .

Lets say I added User1 and User2.

User1 send message: ConcurrentModificationException

User2 sends message : No exception. The code loops at Arraylist. Finds both sockets and tries to send message to both. But the message reaches only User 1

Another issue I have in code is that whenever I close window on any one of the users ChatServer throws exception that the socket was closed. Please note that all this is happening my local machine. Both users occupy different ports though.

Here is the whole code:

ChatServer.Java

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStreamReader;

import java.io.PrintWriter;

import java.net.ServerSocket;

import java.net.Socket;

import java.util.ArrayList;

import java.util.Date;

import java.util.Iterator;

public class ChatServer implements Runnable {

private static int port;

private static String ip_add;

private Socket socket;

private ArrayList clients;

private ServerSocket ss;

public ChatServer(String ip_add_in, int port_in) {

// TODO Auto-generated constructor stub

port = port_in;

ip_add = ip_add_in;

clients = new ArrayList();

}

@Override

public void run() {

// TODO Auto-generated method stub

System.out.println("ChatServer Start!!" + new Date() );

try {

ss = new ServerSocket(port, 10);

while(true){

socket = ss.accept();

System.out.println("ChatServer Accepts!!" + new Date() );

clients.add(socket);

sendWelcomeMessage();

Thread transmit = new Thread(new transmitMessagestoAll(socket));

transmit.setName("" + socket.getPort());

transmit.start();

// (new Thread(new cleanUp(clients))).start();

if(clients.isEmpty()) {

System.out.println("All users Gone");

break;

}

}

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

public void sendWelcomeMessage() {

// send message via writer

}

public class transmitMessagestoAll implements Runnable {

private ArrayList clientList;

private Socket currentClient;

private BufferedReader reader;

private PrintWriter writer;

String msg;

public transmitMessagestoAll(Socket curr){

clientList = new ArrayList();

clientList = clients;

currentClient = curr;

}

@Override

public void run() {

// TODO Auto-generated method stub

System.out.println(Thread.currentThread().getName());

while(!clientList.isEmpty()){

System.out.println(clientList.size());

try {

reader = new BufferedReader(new InputStreamReader(currentClient.getInputStream()));

msg = reader.readLine();

while(msg!=null){

for (Socket thisClient : clientList) {

System.out.println(Thread.currentThread().getName()

+ ">>>>>"

+ thisClient.getPort());

writer = new PrintWriter(thisClient.getOutputStream());

System.out.println("Transmitting");

writer.println(msg);

writer.flush();

msg = reader.readLine();

}

System.out.println("-----------------");

}

} catch (IOException e) {

// TODO Auto-generated catch block

System.out.println("All users Gone! Breaking");

e.printStackTrace();

break;

}

}

}

}

Chat1.Java

import java.awt.*;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStreamReader;

import java.io.PrintWriter;

import java.net.ServerSocket;

import java.net.Socket;

import java.net.UnknownHostException;

import java.util.*;

import javax.swing.*;

import javax.xml.ws.handler.MessageContext.Scope;

public class Chat1 {

JFrame frame;

JPanel msg_pan, chat_pan,connect_pan;

JButton send,connect;

JTextField server_ip;

JTextArea type_area, chat_area;

private static String user;

private SendMsg send_action = new SendMsg();

private Connect connect_action = new Connect();

private Socket writerSocket;

// private Socket readerSocket;

static String ip_address;

static int port;

private PrintWriter writer;

private ReaderThread readerRunner;

private SenderThread senderRunner;

Thread senderThread;

Thread readerThread;

public Chat1(String name, String ip_add_in, int port_in){

user = name;

ip_address = ip_add_in;

port = port_in;

}

public void create_window() {

// GUI and add action Listeners

}

class SendMsg implements ActionListener{

@Override

public void actionPerformed(ActionEvent e) {

// TODO Auto-generated method stub

String msg = type_area.getText();

if (msg != null && msg != "") {

msg = user + " :: " + msg ;

senderRunner = new SenderThread(msg);

type_area.setText(null);

senderThread = new Thread(senderRunner);

senderThread.start();

}

}

}

public void startchat(){

create_window();

// System.out.println("Window Done");

connect_socket();

}

public void connect_socket(){

try {

System.out.println("Start Chat" + new Date());

System.out.println(ip_address);

System.out.println(port);

writerSocket = new Socket(ip_address,port);

if(writerSocket.isBound())

{

readerRunner = new ReaderThread();

readerThread = new Thread(readerRunner);

readerThread.start();

System.out.println("Thread Started");

}

} catch (UnknownHostException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

public class ReaderThread implements Runnable {

InputStreamReader streamReader;

BufferedReader reader;

String msg;

public void run(){

try {

System.out.println("Entered ReaderThread Run");

streamReader = new InputStreamReader(writerSocket.getInputStream());

reader = new BufferedReader(streamReader);

while (true) {

msg = reader.readLine();

if (msg != null) {

msg = msg + "\n";

chat_area.append(msg);

}

}

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

System.out.println("Leaving ReaderThread Run");

}

}

public class SenderThread implements Runnable{

String msg;

public SenderThread(String msg_in){

msg = msg_in + "\n";

}

public void run(){

System.out.println("Entered SenderThread Run" + msg);

try {

if (writer == null) {

writer = new PrintWriter(writerSocket.getOutputStream());

}

System.out.println("Writer has Error-->" + writer.checkError());

writer.println(msg);

writer.flush();

// writer.close();

} catch (UnknownHostException e) {

// TODO Auto-generated catch block

System.out.println("Sender Thread Run Exception 1");

e.printStackTrace();

} catch (IOException e) {

// TODO Auto-generated catch block

System.out.println("Sender Thread Run Exception 2");

e.printStackTrace();

}

System.out.println("Leaving SenderThread Run");

}

}

}

解决方案

I found the bug in the code. While the code was pushing out messages to all clients there was a readLine method call which effectively wiped out the text so it was pushing blank lines to second and other clients. with that fix the issue with concurrentmodification also went away. I can post the whole code for anyone who might be working on similar lines. Just add a comment and I will post it..

Code Correction:

Class ChatServer

Inner class : transmitMessagestoAll

Method Run, inside the loop on clientList the call to readLine was moved to outside the loop.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值