This program is a socket chat program based on the Java language. It uses the TCP transmission protocol to achieve information interaction between two people. Before the final result was formed, I went through two process programs, both of which were semi-finished products. They reflected my thinking process in the course design. After a systematic thinking process, the socket thought layer-by-layer reinforcement has profoundly impressed my image and gained a lot. In this document, I will demonstrate the thinking process of the two process programs, and then explain the source code, but the final uploaded code is finished. Testserver1 and testclient1 are the first processes, testserver2 and testclient2 are the second processes, and mysinglethreadserver1 and mysinglethreadclient1 are the final processes. Among them, testserver2 and testclient2 implement multithreading, one thread is responsible for receiving, the other thread is responsible for sending, and mysinglethreadserver1 and mysinglethreadclient1 implement Gui-based chat. Controls are not easily implemented by dragging components like MFC. Java is implemented by programming. I use AWT component encoding to implement gui. The interface is very simple, but it took a lot of time to layout. Core code explanation: the three Process Programs involve the core idea of Java socket programming. 1. the server-side Java Socket server needs to introduce two packages, Java. the IO package and java.net package are used to solve the problem of input and output streams, while the net package contains the APIS required for socket programming. the server first needs to obtain the serversocket object, that is, serversocket Ss = new serversocket (5555); 5555 is the server port number. Socket S = ss. Accept (); the server socket object starts to listen to the client information linked through the accept () method. If a client has information, the object s calls the input/output stream method, such as S. getinputstream () encapsulates the obtained inputstream in datainputstream. When the client communicates with the server, the two ends may exist in different operating systems, encapsulated in datainputstream can solve this problem well. 2. In fact, the client code is mostly similar to that on the server. There is no serversocket class on the client, that is, the client does not need to listen to any link, but only needs to send a link. Socket S = new socket (string ipaddr, int port), ipaddr is the IP address of the server, and port is the port number of the server, that is, 5555. Because the server and client of this program are on the same host, therefore, the server IP address is 127.0.0.1. The socket object s can be obtained through the ipaddr and port parameters. The subsequent steps are similar to those of the server program. Procedure1: the core server code is as follows: serversocket Ss = new serversocket (5555); socket S = ss. accept (); outputstream OS = S. getoutputstream (); dataoutputstream dos = new dataoutputstream (OS); inputstream is = S. getinputstream (); datainputstream Dis = new datainputstream (is); inputstreamreader ISR = new inputstreamreader (system. in); // read data through the keypad bufferedreader BR = new bufferedreader (ISR); // put the data read from the keyboard into a slow state Punch string Info; while (true) {info = dis. readutf (); system. out. println ("client:" + info); If (info. equals ("goodbye") {break;} info = BR. readline (); dos. writeutf (Info); system. out. println ("the server says:" + info); If (info. equals ("goodbye") {break;} core client code: Socket S = new socket ("127.0.0.1", 5555); inputstream is = S. getinputstream (); datainputstream Dis = new datainputstream (is); outputstream OS = S. geto Utputstream (); dataoutputstream dos = new dataoutputstream (OS); inputstreamreader ISR = new inputstreamreader (system. in); bufferedreader BR = new bufferedreader (ISR); string Info; while (true) {info = BR. readline (); system. out. println ("the client said:" + info); dos. writeutf (Info); If (info. equals ("goodbye") {break;} info = dis. readutf (); // The blocking function system. out. println ("the server says:" + info); If (info. equals ("goodby E ") {break;} the server and client are different in the while (true) loop, and the server is dis. readutf (), you must first read the information sent from the client to use info = BR. readline (); dos. writeutf (Info); read information from the keyboard and send it to the client. On the contrary, the client must first read the keyboard information through Br. Readline (); to receive the information sent by the server. Thought 1: This simple chat program has already achieved information exchange between the server and the client, but now there is an inevitable problem. For example, in terms of the server, when the server passes through DOS. after writeutf (Info) sends a message to the client, it will execute info = dis again in the while loop body. readutf () code, while readutf () is a blocking function. If the client does not send the code, it will block it in that place. At this time, the following part of the code dos. writeutf (Info) cannot be executed, that is, the server cannot send messages. How can we solve this problem? How can I send a message when readutf () is blocked and writeutf (Info) is used? Obviously, when one path fails, we should consider another path. Therefore, multithreading is introduced here. Procedure2 is like this. Procedure2: Compared with procedure1, procedure2 adds multithreading. One thread is responsible for receiving messages and the other for sending messages. When the server is responsible for receiving the thread because readutf () is blocked and cannot send messages, the thread responsible for sending messages allows the server to send messages as well. The same is true for clients. The key code added to the server is as follows: Class serverreadthread extends thread {private datainputstream DIS; Public serverreadthread (datainputstream dis) {This. dis = DIS;} public void run () {string Info; try {While (true) {info = dis. readutf (); system. out. println ("client:" + info); If (info. equals ("goodbye") {system. out. println ("client bye! "); System. exit (0) ;}} catch (ioexception e) {e. printstacktrace () ;}} class serverwritethread extends thread {private dataoutputstream DOS; private bufferedreader BR; Public serverwritethread (dataoutputstream dos, bufferedreader BR) {This. DOS = DOS; this.br = BR;} public void run () {string Info; try {While (true) {info = BR. readline (); dos. writeutf (Info); If (info. equals ("bye") {system. exit (0 );}} Catch (ioexception e) {e. printstacktrace () ;}} is responsible for accepting the class serverreadthread to inherit the thread, and constructing a constructor of the datainputstream object parameters to receive information from the other party. The serverwritethread class is responsible for sending messages by inheriting the thread and constructing a double parameter constructor for the datainputstream object and bufferedread object. New serverreadthread (DIS). Start (); New serverwritethread (DOS, Br). Start (); enable two threads. The principle of the client is similar to that of the server. Thinking 2: Compared with procedure1, procedure2 has implemented multi-threaded chat. Although it is only running on the console, it is small and dirty, which reflects the core idea of Java socket programming and multithreading, the purpose of this course has been achieved. To achieve a more user-friendly effect, I introduced the javagui component AWT and related technologies, such as Event-based Drivers and calls between various AWT components. At the same time, the Code distribution and organizational structure should be adjusted accordingly. Procedure3 is an event-driven component. Therefore, the mysinglethreadserver1 class must inherit the actionlistener interface and implement the unique actionreceivmed (actionevent e) method. When an event is triggered, execute the code in this method. The key code is as follows: public class mysinglethreadserver1 implements actionlistener {private frame F; private textarea TA1 = newtextarea ("", 5, 40, textarea. scrollbars_vertical_only); Private textarea TA2 = new textarea ("", 16, 52, textarea. scrollbars_vertical_only); Private button B; private string MSG = ""; outputstream OS; dataoutputstream DOS; inputstream is; datainputstream DIS; serversocket SS; socket s; Public mysinglethr Eadserver1 () {f = new frame ("server: Pony"); B = new button ("server send"); F. setbackground (color. white); B. setbackground (color. light_gray); ta1.setbackground (color. light_gray); ta2.setbackground (color. light_gray); ta2.seteditable (false); // set to only be read f. setlayout (New flowlayout (flowlayout. left); F. add (TA1); F. add (B); F. add (TA2); F. set location (200,200); F. setsize (400,400); F. setresizable (false); f. Setvisible (true); B. addactionlistener (this); F. addwindowlistener (New windowadapter () {public void windowclosing (invalid wevent e) {system. exit (0) ;}}); try {Ss = new serversocket (7777); s = ss. accept (); is = S. getinputstream (); Dis = new datainputstream (is); OS = S. getoutputstream (); dos = new dataoutputstream (OS); serverreadsome (); // accept the information sent from the client} catch (ioexception e) {e. printstacktrace () ;}} publi C void actionreceivmed (actionevent e) {// The time when the server clicks the button. Try {MSG = ta1.gettext (); dos. writeutf (MSG); ta2.append ("Pony:" + MSG + "/N"); ta1.settext (""); ta1.requestfocus ();} catch (ioexception IOE) {IOE. printstacktrace () ;}} public void serverreadsome () {try {While (true) {MSG = dis. readutf (); ta2.append ("Xiao Xu:" + MSG + "/N") ;}} catch (ioexception IOE) {IOE. printstacktrace () ;}} public static void main (string ARG S []) {New mysinglethreadserver1 () ;}} I put the GUI initialization information and event-driven information to the constructor of mysinglethreadserver1, so that this class is initialized when a new one is created. Think 3: Since the objects of datainputstream, dataoutputstream, inputstream, outputstream, serversocket, and socket are global variables, I have not moved the input and output operations on these class objects to main () in the function, it should be a static variable or method that must be required in the main () function, So I simply put the operation on the input and output stream into the constructor. At the same time, the corresponding logic processing is implemented in the actionevent med (actionevent e) method body. After a great deal of code debugging, we finally realized information interaction between the two. Because it is a single thread, I thought procedure3 would also be blocked by readutf () Like procedure1, and the results were unexpected. The small chat program based on AWT did not see the expected bad phenomenon, that is, after one Party sends the message, it must wait for the other party to respond before sending the message again. procedure3 directly shows the function that can be implemented by multithreading in procedure2. It's strange that it's just God's eye open, knowing that I'm trying to let me go. Analyze the code carefully to find out why. The reason is that the actionreceivmed () method is responsible for sending messages. When you click the button, actionreceivmed () is triggered to send messages. If one party edits the message and clicks the button, the message is sent to the other party, it is not affected by the readutf () blocking function. So strictly speaking, procedure3 is only a single-threaded program, and it implements a function that can be implemented by multiple threads. Conclusion: only by implementing the expected functions in hands-on practice can we make ourselves grow faster. Although the results are small, they enjoy the process of gradually thinking. If any reprint is available, please describe the source!
The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion;
products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the
content of the page makes you feel confusing, please write us an email, we will handle the problem
within 5 days after receiving your email.
If you find any instances of plagiarism from the community, please send an email to:
info-contact@alibabacloud.com
and provide relevant evidence. A staff member will contact you within 5 working days.
A Free Trial That Lets You Build Big!
Start building with 50+ products and up to 12 months usage for Elastic Compute Service