java – 使用套接字的多线程客户端 – 服务器聊天
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java – 使用套接字的多线程客户端 – 服务器聊天,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含5550字,纯文字阅读大概需要8分钟。
内容图文
![java – 使用套接字的多线程客户端 – 服务器聊天](/upload/InfoBanner/zyjiaocheng/699/99ce0f722b0b49b096e692cef886ae64.jpg)
服务器和客户端使用我自己的协议进行通信,看起来像XMPP.我应该实现聊天应用.因此,当一个用户写入字符串时,它应该通过服务器发送给其他客户端.我在服务器上有方法sendToAll.但是用户只有在按下回车键时才会看到其他用户的消息.
用户如何在不按输入按钮的情况下接收消息?
所以这是我的客户:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import org.apache.log4j.Logger;
import dataart.practice.protocols.XMLProtocol;
public class Client {
public static final String SERVER_HOST = "localhost";
public static final Integer SERVER_PORT = 4444;
public static final Logger LOG = Logger.getLogger(Client.class);
private static BufferedReader in;
private static PrintWriter out;
private static BufferedReader inu;
public static void main(String[] args) throws IOException {
System.out.println("Welcome to Client side");
XMLProtocol protocol = new XMLProtocol();
Socket fromserver = null;
fromserver = new Socket(SERVER_HOST, SERVER_PORT);
in = new BufferedReader(new InputStreamReader(fromserver.getInputStream()));
out = new PrintWriter(fromserver.getOutputStream(), true);
inu = new BufferedReader(new InputStreamReader(System.in));
String fuser, fserver;
while (true){
if(in.ready()){//fserver = in.readLine()) != null) {
System.out.println("asdasdsd");
fuser = inu.readLine();
if (fuser != null) {
if (fuser.equalsIgnoreCase("close"))
break;
if (fuser.equalsIgnoreCase("exit"))
break;
protocol.setComId((long) 0);
protocol.setContent(fuser);
protocol.setLogin("Guest");
try {
JAXBContext jaxbContext = JAXBContext.newInstance(XMLProtocol.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
jaxbMarshaller.setProperty(Marshaller.JAXB_FRAGMENT, false);
jaxbMarshaller.marshal(protocol, out);
out.flush();
} catch (JAXBException e) {
LOG.error("Error while processing protocol" + e);
}
}
}
}
out.close();
in.close();
inu.close();
fromserver.close();
}
}
和ServerThread服务器.
public static void main(String[] args) throws IOException {
LOG.trace("Server started");
ServerSocket s = new ServerSocket(SERVER_PORT);
try {
while (true) {
LOG.trace("Waiting for connections...");
Socket socket = s.accept();
try {
// new ServerThread(socket);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
userCounter++;
addUser("Guest" + userCounter, out);
LOG.trace("User " + userCounter + " has been added!");
exec.execute(new ServerThread(socket, in, out));
} catch (IOException e) {
socket.close();
}
}
} finally {
s.close();
}
}
ServerThread.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringReader;
import java.net.Socket;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.transform.stream.StreamSource;
import org.apache.log4j.Logger;
import dataart.practice.protocols.XMLProtocol;
import dataart.practice.serverUtils.Commands;
public class ServerThread implements Runnable {
private static final Logger LOG = Logger.getLogger(ServerThread.class);
private XMLProtocol protocol;
private Socket socket;
private BufferedReader in;
private PrintWriter out;
private String buffer = "";// may be exist another. way but it's not working
private Boolean login = false;
public ServerThread(Socket s, BufferedReader in, PrintWriter out) throws IOException {
this.in = in;
this.out = out;
out.println("</XMLProtocol>");
socket = s;
new Thread(this);
}
public void run() {
try {
while (true) {
if ((buffer = in.readLine()) != null) {
if (buffer.endsWith("</XMLProtocol>")) {
protocol = getProtocol(buffer);
//Server.onlineUserList.put(protocol.getLogin(), out);
/* if (!login){
out.println("Maybe login first?");
}
*/
LOG.trace("Getting message from user: " + protocol.getLogin() + " recived message: " + protocol.getContent());
///out.println(protocol.getLogin() + " says:" + protocol.getContent());
Server.sendToAll(protocol.getContent()+"</XMLProtocol>");
} else {
LOG.trace("Nop protocol do not send with it end");
}
}
}
} catch (IOException e) {
LOG.error("Error in reading from stream: " + e);
} catch (JAXBException e) {
LOG.error("Error in Marshalling: " + e);
} finally {
try {
socket.close();
LOG.trace("Socket closed");
} catch (IOException e) {
LOG.error("Socket no closed" + e);
}
}
}
public XMLProtocol getProtocol(String buffer) throws JAXBException {
JAXBContext jaxbContext = JAXBContext.newInstance(XMLProtocol.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
return (XMLProtocol) jaxbUnmarshaller.unmarshal(new StreamSource(new StringReader(buffer)));
}
public Boolean loginIn(XMLProtocol protocol) {
return true;
}
}
解决方法:
您将需要多线程客户端和服务器.客户端需要一个线程来监听来自服务器的消息,并将它们写入他/她的屏幕,以及一个等待他/她的键盘输入并将其发送到服务器的线程.同样地,对于到服务器的每个连接,它将需要等待来自客户端的输入的线程以及将来自其他用户的输出发送到客户端的一个线程.
在您按Enter键之前看不到传入消息的原因是因为客户端while循环.现在已经注释掉了,但看起来你的循环习惯了:
– 从服务器读取传入消息
– 从键盘读取输入
– 将输入发送到服务器
因此,您阅读服务器上可用的任何内容,然后客户端再次从服务器读取之前等待更多键盘输入(在下一次迭代中).
根据我的理解,另一个建议是创建JAXBContext,这可能是一项昂贵的操作.每次发送消息时都不需要重新创建它.考虑在服务器和客户端初始化一个,然后为每个marshall / unmarshall重用它.
内容总结
以上是互联网集市为您收集整理的java – 使用套接字的多线程客户端 – 服务器聊天全部内容,希望文章能够帮你解决java – 使用套接字的多线程客户端 – 服务器聊天所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。