This article mainly introduces Java Socket chat room programming (2) Using sockets to achieve single chat room related materials, very good, has reference value, the friends you need can refer to
In the previous article, Java Socket Chat Room Programming (1) Using sockets to push chat messages, we talked about how to use sockets to get messages between the server and the client so that they can be pushed. Next, I will write how to get the server to establish communication between the client and the client.
In fact, it is to establish a one-to-one chat communication.
Unlike the previous code that implemented message push, it was modified on top of it.
If no methods or classes are mentioned, they are identical to the previous one.
1, Modify entity classes (server-side and client-side entity classes are the same)
1, UserInfoBean User Information Table
public class UserInfoBean implements Serializable { private static final long serialVersionUID = 2L; private long userId;//User id private String userName;//User name private String likeName;//Nickname private String userPwd;//User password private String userIcon;//User Avatar //Omit get, set methods }
2, MessageBean Chat Information Table
public class MessageBean implements Serializable { private static final long serialVersionUID = 1L; private long messageId;//Message id private long groupId;//Group id private boolean isGoup;//Is it a group message? private int chatType;//Message Type; 1, Text; 2, Picture; 3, Small Video; 4, File; 5, Geographic Location; 6, Voice; 7, Video Call private String content;//Text message content private String errorMsg;//Error message private int errorCode;//Error Code private int userId;//User id private int friendId;//Target Friend id private MessageFileBean chatFile;//Message Attachment //Omit get, set methods }
3, MessageFileBean message attachment table
public class MessageFileBean implements Serializable { private static final long serialVersionUID = 3L; private int fileId;//file id private String fileName;//File Name private long fileLength;//file length private Byte[] fileByte;//File Content private String fileType;//file type private String fileTitle;//File Header Name //Omit get, set methods }
2, (Server-side code modification) ChatServer's main chat service class, to modify
public class ChatServer { //socket Service private static ServerSocket server; //Use ArrayList to store all Socket s public List<Socket> socketList = new ArrayList<>(); //Imitate socket s stored in memory public Map<Integer, Socket> socketMap = new HashMap(); //Imitate user information stored in the database public Map<Integer, UserInfoBean> userMap = new HashMap(); public Gson gson = new Gson(); /** * Initialize socket service */ public void initServer() { try { //Create a ServerSocket to listen for client requests on port 8080 server = new ServerSocket(SocketUrls.PORT); createMessage(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * Create message management and receive messages all the time */ private void createMessage() { try { System.out.println("Waiting for user access : "); //Use accept() to block waiting for customer requests Socket socket = server.accept(); //Save the linked socket in the collection socketList.add(socket); System.out.println("User Access : " + socket.getPort()); //Open a sub-thread to wait for another socket to join new Thread(new Runnable() { public void run() { //Create a socket service again waiting for other users to access createMessage(); } }).start(); //Used by server to push messages to users getMessage(); //Get information from the client BufferedReader bff = new BufferedReader(new InputStreamReader(socket.getInputStream())); //Read incoming server information String line = null; //Loop keeps receiving messages from the current socket while (true) { Thread.sleep(500); //System.out.println("Content:"+ bff.readLine())); //Get client information while ((line = bff.readLine()) != null) { //Resolve Entity Classes MessageBean messageBean = gson.fromJson(line, MessageBean.class); //Add user information to the map, mimic adding to database and memory //Entity classes are stored in the database, socket s are stored in memory, and user IDs are used as references setChatMap(messageBean, socket); //Forward incoming messages to target friends getFriend(messageBean); System.out.println("user : " + userMap.get(messageBean.getUserId()).getUserName()); System.out.println("content : " + messageBean.getContent()); } } // server.close(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); System.out.println("error : " + e.getMessage()); } } /** * send message */ private void getMessage() { new Thread(new Runnable() { public void run() { try { String buffer; while (true) { //Enter from console BufferedReader strin = new BufferedReader(new InputStreamReader(System.in)); buffer = strin.readLine(); //Because readLine ends with a line break, a line break is added at the end buffer += " "; //Modified here to push messages to all users connected to the server for (Socket socket : socketMap.values()) { OutputStream output = socket.getOutputStream(); output.write(buffer.getBytes("utf-8")); //Send data output.flush(); } } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }).start(); } /** * Simulate adding information into database and memory * * @param messageBean * @param scoket */ private void setChatMap(MessageBean messageBean, Socket scoket) { //Save user information if (userMap != null && userMap.get(messageBean.getUserId()) == null) { userMap.put(messageBean.getUserId(), getUserInfoBean(messageBean.getUserId())); } //Save the socket with the corresponding link in if (socketMap != null && socketMap.get(messageBean.getUserId()) == null) { socketMap.put(messageBean.getUserId(), scoket); } } /** * Simulate user information for the database, where user information with different IDS is created * * @param userId * @return */ private UserInfoBean getUserInfoBean(int userId) { UserInfoBean userInfoBean = new UserInfoBean(); userInfoBean.setUserIcon("User Portrait"); userInfoBean.setUserId(userId); userInfoBean.setUserName("admin"); userInfoBean.setUserPwd("123123132a"); return userInfoBean; } /** * Forward message to target friend * * @param messageBean */ private void getFriend(MessageBean messageBean) { if (socketMap != null && socketMap.get(messageBean.getFriendId()) != null) { Socket socket = socketMap.get(messageBean.getFriendId()); String buffer = gson.toJson(messageBean); //Because readLine ends with a line break, a line break is added at the end buffer += " "; try { //Send information to client OutputStream output = socket.getOutputStream(); output.write(buffer.getBytes("utf-8")); //Send data output.flush(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
3, (Client Code) LoginActivity login page modification allows multiple logins
public class LoginActivity extends AppCompatActivity { private EditText chat_name_text, chat_pwd_text; private Button chat_login_btn; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_login); chat_name_text = (EditText) findViewById(R.id.chat_name_text); chat_pwd_text = (EditText) findViewById(R.id.chat_pwd_text); chat_login_btn = (Button) findViewById(R.id.chat_login_btn); chat_login_btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { int status = getLogin(chat_name_text.getText().toString().trim(), chat_pwd_text.getText().toString().trim()); if (status == -1 || status == 0) { Toast.makeText(LoginActivity.this, "Password error", Toast.LENGTH_LONG).show(); return; } getChatServer(getLogin(chat_name_text.getText().toString().trim(), chat_pwd_text.getText().toString().trim())); Intent intent = new Intent(LoginActivity.this, MainActivity.class); startActivity(intent); finish(); } }); } /** * Return to login status, 1 for user and 2 for another user, where two users are simulated communicating with each other * * @param name * @param pwd * @return */ private int getLogin(String name, String pwd) { if (TextUtils.isEmpty(name) || TextUtils.isEmpty(pwd)) { return 0;//No full password was entered } else if (name.equals("admin") && pwd.equals("1")) { return 1;//User 1 } else if (name.equals("admin") && pwd.equals("2")) { return 2;//User 2 } else { return -1;//Password error } } /** * Instantiate a chat service * * @param status */ private void getChatServer(int status) { ChatAppliaction.chatServer = new ChatServer(status); } }
4, (Client Code) Modification of ChatServer Chat Service Code Logic
public class ChatServer { private Socket socket; private Handler handler; private MessageBean messageBean; private Gson gson = new Gson(); //Obtain output stream from Socket object and construct PrintWriter object PrintWriter printWriter; InputStream input; OutputStream output; DataOutputStream dataOutputStream; public ChatServer(int status) { initMessage(status); initChatServer(); } /** * Message Queue, used to deliver messages * * @param handler */ public void setChatHandler(Handler handler) { this.handler = handler; } private void initChatServer() { //Start Thread to Receive Messages receiveMessage(); } /** * Initialize user information */ private void initMessage(int status) { messageBean = new MessageBean(); UserInfoBean userInfoBean = new UserInfoBean(); userInfoBean.setUserId(2); messageBean.setMessageId(1); messageBean.setChatType(1); userInfoBean.setUserName("admin"); userInfoBean.setUserPwd("123123123a"); //The following action mimics saving the user id and the chat target user id when the user clicks on a friend's expanded chat interface if (status == 1) {//If User 1, he chats to User 2 messageBean.setUserId(1); messageBean.setFriendId(2); } else if (status == 2) {//If User 2, he chats to User 1 messageBean.setUserId(2); messageBean.setFriendId(1); } ChatAppliaction.userInfoBean = userInfoBean; } /** * send message * * @param contentMsg */ public void sendMessage(String contentMsg) { try { if (socket == null) { Message message = handler.obtainMessage(); message.what = 1; message.obj = "The server is down"; handler.sendMessage(message); return; } byte[] str = contentMsg.getBytes("utf-8");//Convert content to utf-8 String aaa = new String(str); messageBean.setContent(aaa); String messageJson = gson.toJson(messageBean); /** * Because readLine() on the server side is blocking reads * If it can't read a line break or the end of the output stream will always be blocked there * So put a line break at the end of the json message to tell the server that the message has been sent * */ messageJson += " "; output.write(messageJson.getBytes("utf-8"));//Line Break Printing output.flush(); //Refresh the output stream so that Server receives the string immediately } catch (Exception e) { e.printStackTrace(); Log.e("test", "Error:" + e.toString()); } } /** * Receive messages, in subthreads */ private void receiveMessage() { new Thread(new Runnable() { @Override public void run() { try { //Make a client request to port 8080 of this machine socket = new Socket(SocketUrls.IP, SocketUrls.PORT); //Get input stream from Socket object and construct corresponding BufferedReader object printWriter = new PrintWriter(socket.getOutputStream()); input = socket.getInputStream(); output = socket.getOutputStream(); dataOutputStream = new DataOutputStream(socket.getOutputStream()); //Get information from the client BufferedReader bff = new BufferedReader(new InputStreamReader(input)); //Read incoming server information String line; while (true) { Thread.sleep(500); //Get client information while ((line = bff.readLine()) != null) { Log.i("socket", "content : " + line); MessageBean messageBean = gson.fromJson(line, MessageBean.class); Message message = handler.obtainMessage(); message.obj = messageBean.getContent(); message.what = 1; handler.sendMessage(message); } if (socket == null) break; } output.close();//Close Socket Output Stream input.close();//Close Socket Input Stream socket.close();//Close Socket } catch (Exception e) { e.printStackTrace(); Log.e("test", "Error:" + e.toString()); } } }).start(); } public Socket getSocekt() { if (socket == null) return null; return socket; } }
As a result, code logic has changed from message pushing logic to chatting logic.
This code allows users 1 and 2 to chat with each other, and the server records the chat between them.The server also has the ability to push messages.
The above is the Java Socket Chat Room Programming (2) which is introduced by Xiaobian. It uses sockets to realize chat room. I hope it will be helpful to you. If you have any questions, please leave a message for me.
"We believe that everyone can become a java development god. Now, find a buddy to take you to the beginning and stop being confused on your way to study.This is a java development seminar where beginners move to the Internet industry."
I have been developing for more than 10 years. If you have questions about how to learn java, the learning route and whether you don't know whether you should study or train yourself, you can always ask me. You can add my java to exchange learning qun:615741636.There are learning tutorials and development tools within qun.