English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
In the previous article Java Socket Chat Room Programming (I) Using Socket to Implement Chat Message Push, we talked about how to use socket to pass messages between the server and the client to achieve the purpose of message push. Next, I will write how to make the server establish communication between clients and clients.
It is actually to establish a one-to-one chat communication.
The code for implementing message push in the previous article is slightly different, and it has been modified on top of it.
If there are no mentioned methods or classes, they are exactly the same as the previous one.
1The modification of the entity class (the entity class on the server side and the client side is the same)
1The UserInfoBean user information table
public class UserInfoBean implements Serializable { private static final long serialVersionUID = 2L; private long userId;// User id private String userName;// Username private String likeName;// Nickname private String userPwd;// User password private String userIcon;// User avatar //Omit get and set methods }
2The 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 isGroup;// Is it a group message? private int chatType;// Message type;1,text;2,image;3,short video;4,file;5,location information;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 and 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 and set methods }
2,(server-side code modification)ChatServer is the main chat service class, with modifications
public class ChatServer { // socket service private static ServerSocket server; // Use ArrayList to store all the Sockets public List<Socket> socketList = new ArrayList<>(); // Imitate the sockets stored in memory public Map<Integer, Socket> socketMap = new HashMap(); // Imitate the 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 on port808Listen to customer requests server = new ServerSocket(SocketUrls.PORT); createMessage(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * Create message management, keep receiving messages */ private void createMessage() { try { System.out.println("Waiting for user connection : "); // Use accept() to block and wait for customer requests Socket socket = server.accept(); // Save the incoming socket to the collection socketList.add(socket); System.out.println("User connected : ", + socket.getPort()); // Start a child thread to wait for another socket to join new Thread(new Runnable() { public void run() { // Create another socket service to wait for other users to connect createMessage(); } }).start(); // Used to push messages to users by the server getMessage(); // Obtain information from the client BufferedReader bff = new BufferedReader(new InputStreamReader(socket.getInputStream())); // Read the information sent from the server String line = null; // Keep receiving the messages sent from the current socket in a loop while (true) { Thread.sleep(500); // System.out.println("Content : ", + bff.readLine()); // Obtain client information while ((line = bff.readLine()) != null) { // Parse the entity class MessageBean messageBean = gson.fromJson(line, MessageBean.class); // Add the user information to the map, simulating the addition to the database and memory // The entity class is stored in the database, and the socket is stored in memory, both with user id as the reference setChatMap(messageBean, socket); // Forward the message sent by the user to the target friend getFriend(messageBean); System.out.println("User : ", + userMap.get(messageBean.getUserId()).getUserName()); System.out.println("Content : ", + messageBean.getContent()); } } // server.close(); } // 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) { // Input from console BufferedReader string = new BufferedReader(new InputStreamReader(System.in)); buffer = string.readLine(); // Since readLine ends with a newline character, a newline is added at the end buffer += "\n"; // Modify this 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"));-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) { // Store the user information if (userMap != null && userMap.get(messageBean.getUserId()) == null) { userMap.put(messageBean.getUserId(), getUserInfoBean(messageBean.getUserId())); } // Store the corresponding incoming socket if (socketMap != null && socketMap.get(messageBean.getUserId()) == null) { socketMap.put(messageBean.getUserId(), scoket); } } /** * Simulate database user information, creating user information with different ids here * * @param userId * @return */ private UserInfoBean getUserInfoBean(int userId) { UserInfoBean userInfoBean = new UserInfoBean(); userInfoBean.setUserIcon("user avatar"); userInfoBean.setUserId(userId); userInfoBean.setUserName("admin"); userInfoBean.setUserPwd("123123132a"); return userInfoBean; } /** * Forward the message to the 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); // Since readLine ends with a newline character, a newline is added at the end buffer += "\n"; try { // Send information to the client OutputStream output = socket.getOutputStream(); output.write(buffer.getBytes("utf-8"));-8")); // Send data output.flush(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
3,(client code) Modification of LoginActivity login page can log in multiple people
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 the login status,1For the user,2Simulate communication between two users for another user * * @param name * @param pwd * @return */ private int getLogin(String name, String pwd) { if (TextUtils.isEmpty(name) || TextUtils.isEmpty(pwd)) { return 0;//Incomplete password entered } else if (name.equals("admin") && pwd.equals("1")) { return 1;//User1 } else if (name.equals("admin") && pwd.equals("2")) { return 2;//User2 } else { return -1;//Password error } } /** * Instantiate a chat service * * @param status */ private void getChatServer(int status) { ChatAppliaction.chatServer = new ChatServer(status); } }
4,(client code)Modify the ChatServer chat service code logic
public class ChatServer { private Socket socket; private Handler handler; private MessageBean messageBean; private Gson gson = new Gson(); // Get the output stream from the Socket object and construct a PrintWriter object PrintWriter printWriter; InputStream input; OutputStream output; DataOutputStream dataOutputStream; public ChatServer(int status) { initMessage(status); initChatServer(); } /** * Message queue, used to pass messages * * @param handler */ public void setChatHandler(Handler handler) { this.handler = handler; } private void initChatServer() { //Start a 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 operations mimic the chat interface when a user clicks on a friend's chat, saving the user ID and the chat target user ID if (status == 1) {//If it is a user1Then it points to the user2Chat messageBean.setUserId(1); messageBean.setFriendId(2); } else if (status == 2) {//If it is a user2Then it points to the user1Chat 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 has been closed"; 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 the readLine() on the server side is a blocking read * If it cannot read the newline character or the output stream ends, it will block there indefinitely * Therefore, add a newline character at the end of the JSON message to inform the server that the message has been sent * */ messageJson += "\n"; output.write(messageJson.getBytes("utf-8"));// New line print output.flush(); // Refresh the output stream to make the Server receive the string immediately } e.printStackTrace(); Log.e("test", "Error:") + e.toString()); } } /** * Receive messages, in a sub-thread */ private void receiveMessage() { new Thread(new Runnable() { @Override public void run() { try { // To the local8080 port sends a client request socket = new Socket(SocketUrls.IP, SocketUrls.PORT); // Obtain the input stream from the Socket object and construct the corresponding BufferedReader object printWriter = new PrintWriter(socket.getOutputStream()); input = socket.getInputStream(); output = socket.getOutputStream(); dataOutputStream = new DataOutputStream(socket.getOutputStream()); // Obtain information from the client BufferedReader bff = new BufferedReader(new InputStreamReader(input)); // Read the information sent from the server String line; while (true) { Thread.sleep(500); // Obtain 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 } e.printStackTrace(); Log.e("test", "Error:") + e.toString()); } } }).start(); } public Socket getSocekt() { if (socket == null) return null; return socket; } }
In this way, the code logic has been modified from the message push logic to the single chat logic.
This code allows users1With users2Chat with each other, and the server will record their chat history. The server also has the function of message push.
The above is the Java Socket Chat Room Programming (Part Two) introduced by the editor for everyone, using socket to implement a single chat chat room, hoping it will be helpful to everyone. If you have any questions, please leave a message, and the editor will reply to everyone in time. Here, I also want to express my sincere gratitude to everyone for their support of the Yell Tutorial website!
Statement: The content of this article is from the Internet, and the copyright belongs to the original author. The content is contributed and uploaded by Internet users spontaneously. This website does not own the copyright, has not been manually edited, and does not assume relevant legal liability. If you find any content suspected of copyright infringement, please send an email to: notice#oldtoolbag.com (Please replace # with @ when sending an email to report abuse, and provide relevant evidence. Once verified, this site will immediately delete the content suspected of infringement.)