From e245ee91ddf3b03a8d6ee1a847d56c6faeff53af Mon Sep 17 00:00:00 2001 From: "qwen.ai[bot]" Date: Tue, 21 Apr 2026 11:50:10 +0000 Subject: [PATCH] **Title:** Implement comprehensive GUI interfaces for TCP and UDP client-server applications **Key features implemented:** - Added TCPClientGUI.java with complete graphical interface featuring host/port configuration, connection management, message display, and real-time communication - Created TCPServerGUI.java with server controls including port selection, start/stop functionality, and client interaction logging - Implemented UDPClientGUI.java providing UDP-specific client interface with packet transmission and reception handling - Developed UDPServerGUI.java supporting UDP server operations with packet listening and echo response capabilities - Updated .gitignore to exclude compiled Java classes and build artifacts - Integrated Swing components with proper threading for UI updates and network operations - Added connection state management, error handling, and user feedback mechanisms across all interfaces The upgrade delivers full-featured graphical user interfaces that maintain clean separation between UI and networking logic while providing intuitive controls for both TCP and UDP protocols. --- .gitignore | 7 ++ bin/TCP/TCPClient.class | Bin 1939 -> 1660 bytes bin/TCP/TCPServer.class | Bin 3214 -> 2786 bytes bin/UDP/UDPClient.class | Bin 1813 -> 1398 bytes bin/UDP/UDPServer.class | Bin 1987 -> 1619 bytes src/TCP/TCPClientGUI.java | 163 ++++++++++++++++++++++++++++++++++++ src/TCP/TCPServerGUI.java | 133 +++++++++++++++++++++++++++++ src/UDP/UDPClientGUI.java | 172 ++++++++++++++++++++++++++++++++++++++ src/UDP/UDPServerGUI.java | 120 ++++++++++++++++++++++++++ 9 files changed, 595 insertions(+) create mode 100644 .gitignore create mode 100644 src/TCP/TCPClientGUI.java create mode 100644 src/TCP/TCPServerGUI.java create mode 100644 src/UDP/UDPClientGUI.java create mode 100644 src/UDP/UDPServerGUI.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1da6ad9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +``` +# Compiled Java classes +*.class + +# Build directory +bin/ +``` \ No newline at end of file diff --git a/bin/TCP/TCPClient.class b/bin/TCP/TCPClient.class index 1af547e7650ddda1e45833fa224f272c357a46ce..194184d750d82ea94c0ddcb4d4def2f76479e0e3 100644 GIT binary patch literal 1660 zcmZuxO>Y}j6g|%w`;Dg)r*XbKr6n%q!)|E|gwJu^kh)C?q)CX4E5n9~{hChe%vj@b zXctH2zg2=8yY!C}1_P~!|L%45j$4+X?_I-Zm+wFPgHz{$Q9eM{i_TksdPz&$`Gx&6{~jFZTK7- z!&s2x2tQMBEBA%3AqrjA8)cYIt@JAve9v~avdifb#~8yzfY@$kov!`cp6v@y=8o%# zV}j~#34g8W*PA{i3TvAokxF;UQPLoi)eys!l$>Tb)0I5Q`B2Ix$Wl-CTJz2w;fd;o zu&To2IKyD{uw~~+wgXFJXLX#z(+n{(Hb7vQ8Spg#kSzmAY3sc7eq?=+k}heO!39Zr zmRiy$b!4;YQWVeQ1&)-CG%g;SP~l<27u1%J?J!IYEiaQ_)NvVeG(WdVi+`fjozydB}qC5sR1BDpOZ4Qop@ObxGKp5s*=ui^ERGwjWY*X2ZO z($$dpcfRtQI^KfGpweioE4CvTCVOoR_OH7wa!o=<%)(YHMb!+-tMUf?BZR| z{lwa=2@MOlrX!E*45L=HT4>hm9=R9Q{tS+1P>-cZPL4Ro@ebt`^XnOU+x?y(zq+lp|; zsqAB>ybnX(Jk`c*8_$^G-rXLa>t03na4DW?;bkMz!W(6iKSsh(4BkSP5F<>N1nwUG zCGjh}FihS(>85IMLv3Nv;0KZzppouLmpoZ!(TE%vN((n+Zn%5WP2$Nqi$?f>3@+^= zVJe-2E?Kh5qM;l-f{GTT@$A6#h0OIVa(83)h2Hsj(EOAzoWeN(;qSqiMh<25GDIknF-KAt!Tkg7(cB zeelsg;G@HH`w(ViM#dL9(+7WsKfpJ65WjuGB_MSsIs3A{wbr-yx7L3C&#%7$n1$5P zCeWFmTS)LfSGHxv(-08od1P%^iLzB$Nz5-ll0{D-bk(ld-Zg>t@ri;!V9qJY2-*=g z5JX6zJ7ZU5w!XeB-MqD2mIBd?Q?$wj%eB?|U^C#Y+BJnfku=4C>y}*+7#zQsIZmGQ zT)VQ8QVAnBzb(qDXFHXehNwWFkFuRadj80wqhBCgR%utA8jmu_Og^q6y+qC_u1PO~ z0Sqh7rb_nTT96FOY(_=-QrimG8?2Ucsx3yCS{$x>v1xBq^F`)L>JJ}ESC;Nbt0Y|wV*=)(EnPWE+cYa;;|3-$ zDbPh?EdYU`7G5m|(z<{*6s@@8enh<$GEs;ihJ*sW$tyVqHPcdFr(r6Y5AIQ43_*20j;VOEh|=M=&z1Ef*E!0n+9&-BLSWI zmQ;BQ^dH`(-x~+zsjz7SpQttn7RyeJjgdiC!|g*JK03eZI^U>PFffk=_MKHKFB{Zt4SB>WvN-IU$s*X#WV2n`B?*xI~Ch)j9 z*oUVSXcj*AhmRCIS(!A2>r}%p8>T7y_tcs5tm4{jtLnGChP;O5lO^JJHrqPq)ZL=I zWvdsX>*y7lQYXN9urByg0d1V|nc-LCD#1~33{GxAf8v`X{3Qm?1OVz#Ml>t$`1@Y3dx8lHq6jf13I( zhSmDxP4r~dO7~as9aGyyLV3_~F&T(IL)Z*tH_;t81HT~5Zv&qyknV%%5K<1I20r^g z2ZD4TM2Fxm(&}t?HZl9c3gI=AOq*9kTrl{9->Xqi0CBA@uEU^V1U=VAZZ(vwV z!}PVjPkpH(a>%P3B8AV1XQ_xQSi~39eMm&;eV0tf@SN|>J=RJJKk$LNPX<}c;7iVQ zVxstpzG2kJt~vXfF$);lr!k`8fd)%x$oRhj4I>(2{?7vT(7VX}Jw$}EcXaF_eAaB% OH~vkA0!2n|L+M|bXS{U) diff --git a/bin/TCP/TCPServer.class b/bin/TCP/TCPServer.class index 130e84374470dcd6162c9f039b000eb39ec7de84..ac85b1d68ae89953558aea5e0d367f8a5f211c45 100644 GIT binary patch literal 2786 zcmcImSz8lV7=DigCWK*;ML`jxMFj<87rPKeB}zqElpq%EHcSQ>NM_Q>1Vy{AcHftO zz_q=AKJYyCs=esbKhVqmj9ys#o|z;JlE=HklXK>rZ#nPxe&1RC_;>AB04MQd1lv%d zAf%!aRRRt3+M*UqYu0RRYjat+xs8`W|?VDUDmvXL=p+`H<1zLtZf2JL~#2bmP zNkubS1a@Y$1tVcwy5?Rr-8p{cT+MQGwBeir_fP}6Np-Vxxio-avnKCajqF&U}d1Guw;9wB7pR9NpE*c@wD|tNn zkV%27GA0U+ZCZO`ju}ZcvQnN<@g$yN;+#BrJ5)dr;3DX4Ja1XrblPB4F+43R;~Azh zh`OX9*^c2k6@9V@E16x#RdAx1Ixn|GVc(GcWMcYNobpulw4LKj9A{JvAR$nzrBca! zHY=GnQj+UHa!WqqvXsvW>?oGTKz?S%aE#PABQ+ca&kM8_WkXgrUnomoEHgf&;sP!f zlUq`d5f(^bK?f|!!XQQ@3!@vL9#WAsoW&)nbXnF~X=C`ydZ3d-VIH30-BWe;?UT+n{rQ?wiQ7Nvnu9fLhHR3Fyl-4PocXDeq7l;bhJ)K9AcHYsAK~o~BE5SV~%ZU4Fz_#6->uA{# z!=1BJx%w(BMQ{tZ6}&F@=Nkf@Ud4H2n%1JdV8ndv{?Rw6>8|Z83H%f+>4Ku~^t@)J z(nhXx*tQq)+4xox0yCQoCzi5C8TBAHWsaDFi-eX=Cs~B?Fy0dAVB}FhQ_-}^gWlqi z9JQ@z)^^;e2;&`+o=BU9jIQsMd=jM^bZ4&zF2=cl~?2#TkF(2l$0aaw>(+Es_rXmM7j4uRg#tq#t7d_I# z_=H@%M7RPP!d2Uc->1AR;JuXs< z1pnhach2J?`)wYSg9HJDc{s_(Nd#?dJ5YyX*v`k$UYtghR@JbnwI8ATXcGz)Q$hRz zFP)HrtQ>O)_HhLc^+F6U)ew>C;TMAwrx=hKEAuVQ!=W5eqhm&1wB zDqa{lvV!YVqranF#<_-9{J{D3s{GQHAN2%M% zWrT-0HFK8$qP!4?2=xL+ahZJ+u49_Lj#D&oc-Kuzr@$njBxx7zQYe_`wv|+ B)an2L literal 3214 zcmcIm*;gA?9R4m%n2=6e2t}Z+6%{I!AXQs!Nv*cAwb-Q82B~OWhGYr@$xNI~sCD0W z>%Q;WiuFw&z(dcGH$BJWtMC3DeGtEUCxJ=f_~r@RJ9B^g_gn7#@z4CP0QTd8hB|?D z!^va){Lh%~wCQRH2{cX`(?);Zu*ds{#wN|ICs4oFvMq0)z?$x!5rI(B$(d2CL4%Gk z>IF8WEZaO4s!pjyW^TqmFvrL{Z}Y3W|6qGv?L)1zZM zdYKv{E1{vj?ut1Ty^1>#MIZV#Tu;oGfl(wKJ8*-*`f<}6q`>}M&NWN)x-F7y3KlU4?2$MQTqaV@{L0uh?5%NNc!C+p z#ZZTRI&Q=5Oq^RLZr4>j2w)L(;CR`#WnD6=1P;i`NHUc{ua`I^+6f%gaYz<=nAvqz zJss9Ds7|tZr^IGBg0zNIHLa?9=$vy}n$d9-L+mvpm&=rkMTxYTlUN4=Tw+!QA2Qr= zW}|tPeqad~9hV6gg93U<^{rp#48d1;dHu7)^laWTS-~p#0!;x%zf|a6#xt^0X``sR zRm0r^k-SkD%NdeJ7MZV;n2=1CYzjY6GWlkSu7;^NiE&=;i6MkNQlLwE zd0NM#I766a5z7%OVGh=5r4gjSVJX0+2~X;HN)25#B~;ReT_a23Iypq!mLjgr2aDjc zapp(ObFILNG{)7~RtZz(TQSZ;BVk!IFmfpx%{XN@YaX)X&|klFkz6m;uu~5>j#u(r zqnI|m2`5*I;x)XX;dOz|WkZ%d?M#{dzCC}I9x}3?$gN;(*_7xsB>|EX~ zb*3C=s$5L?p$EMWoYV*opDCKFum}5XmBCd}ku>u83@awFp&qYB@V3BKM&99HIURY6 z_lV7_tHZH7WUF?F2;ODMB~=S{WF6b)t!m~5Iz$xj<3kM}2wbxQkCf^?#%Y|YqVW+v z7Fb(YJ`(uz|HtM(fvX|<=?LOlLsp;%>w6VE-)lsDlo!M2I_|^$1o$%^MDR7^K5k}B zYg*wJ!M7~igV_m(Aac455>hvrH#k`Ng>YV=YXzLE6^w=%=I*~)dBytGg{$e-8s7cj z%BukNTs6M+a~Ish+vgDZi4S#%a+PGcuH~xx4BXf8tpV$?fn1Gz4w2F%)rdx_t>=l; z)cnd`krqcUqIq=l99jlKKcj8)JhlR}xTZZci|&CikJ`hti2s5c=doK+E+R479-hao zz#R6^;*OccztZiY-w=^9cg7cv#(zhoFFk{G@xJqj#QSD(SA2nv#E{|-h+vdI8J`Sb z8y%HrA?`7rY^C#EbbU7+K7^}y|LI5*6&c`ma?y1h!`<9Nn8I;n7+MSmF^qe7(uGcp z-~@5ImmJrkevt~p8b*bNBkHdiDDdGDqWifuG&DwK2~ded=N$z&@S{kH^hKN;y@&@# zx6k6?IppRrPOv8BYd$oG;y`EyTNFU^C{;j{zC-$Z=9g@#t9n9nk4rwtVZo!NcGO*iJw%^M^w12Fi}*% zoW)u0z&ZY!DnQ>zAVH`?{H}{&BiClMqJ@yPp_`woyReBL>}~wU*n;!85*G-*1brtl zX+;@N;~8q|!amZUr4}jk9G)ljFwgy`^E`h6FA_}&e-i5#$yTqSuZsRj4U-x_@^A@l zydz~A#9b;6m!SCxS)??x)hCyx5LLfKRdsk7uW;|AxwB+=ORewV6VgA$7x+@Wf2G!M Q@Etj2d!NJi_yO(z0)j<6dH?_b diff --git a/bin/UDP/UDPClient.class b/bin/UDP/UDPClient.class index f92aa13ab8327bbc87f4cf46ea417d6ef3ed18d4..3e20c6faa4a225bfc0efe40a471e6ddd041cef34 100644 GIT binary patch literal 1398 zcmZux-Ez}L7(MI1l@ui*PDrAXfaxE0XkwcFgvta;64II)lh(o1xU^N|9YvCZ;O(ze~S7HYGt!zT**fUzmyJydy?|eu4_vPQm0M=n^h#}6A(2+!n z;mjlJz{hMSFsFM@y=n~X%K!S&g-~<4B6s!$)z`BJEZtEnSys2E^T_G$__;%6MC6@ zTRWLR_y@vY$?P6>M5av+SWOX_8s5hT93Seqge=2!R2Ln6ijaYKBz;TDALUb3%3soP z86Po>?OQ=vJPAvVOTJS39>~=d9eG?~P~4NHne5QusPRM3HLT(jj!$)bhR@%2F=`4i zL|qF7H87FQ)i*eTZ z+Cos4rvGC!`$w9Wrsg{9M^I~hjFm4xhi)dO68J|klSfF`o?)hscg)l?ET%8^@Sc(C zA@?Wl%lop)4c^1YrgDU}nxPoVv5{El;|o(=Hq;)jMbk+mdECdBrnYQoJ!}%u5msyR zc{?u0Vjp*i`01;s%RTH!*|A9WZAw0%AWp(LiJgQ_@9;PlFo7(6o37CMRZQasX0eSq zDsCPRaSo3O@e6tJE6(FLWbixrRU@Vgh`pjsoZ|tLklK0;t;nU-U`nx}Sc;b(l1(@?IVYZTf@Q`h z#|OvhIQG>);EZqffjHvu1N=+QSihYUNKhWmK9{xjx7PaB`u6$jpFfTO%;Rf`E`i>A zORE`Pixo@RzC>8y+^)H2W-6v#&fMABRYhN*`?_UY{`&%8hf#_9&J)+%d4KGndR< zkE8x}*FXVl!Ib5dUG{gH8q4YW*EQ^?^w+RW+(~R0cz{iTo*mO$IiZlMe4rEm+`t!F zj*();@knjhbj##t=nPfSs8ync+SXD_akSMOmo|}OQC?Fq0*N+fr^Uo3Ni)z4CEWJv zlml_L>f77O<$!N4aDx}fbK=W`kAS;8o~pu#rUyrZ^7pX z+%{{?Gf3j0#4h0qPTei4Tb4en`cBTj8O;R+#3t~J1iJXd1CFcYTZVVRdt|DC=x-=~8^`GL{ejYAA?G%&hy`FD(E!vkUb z8O=rxF}d*!$p&7_c0WUUaQXn5U$B$x};?ca*gT} zo+5}PvR>+#o;o}MRYx9no@#)jjWIumPknO*DwkEO)&}v&`sX^7kIp+tpET3 diff --git a/bin/UDP/UDPServer.class b/bin/UDP/UDPServer.class index 141e9091459c021f489456f0a3210417617e88db..ed27e357273c73c8119aba013f144547aa7c6830 100644 GIT binary patch delta 904 zcmY*XOHUI~6#i~I)7zGT@{%&PKrOG9S49xDfR6$y%1a6=)Ynk11%(#dk*FI@+?(Lt zxN~FT!WAxP0*06vH*Vdj8~zA-ZWkISnRCuP-#O>|?&FK^yW#(KxVsNv7#S}daB^q{ zbhx%cVT#>bzk)FiuS%6MXp!;gbq~r>!QnGdi7JN52iB$)TeGs6Sn_GX7VEN|gtPv;GP{>N!jUM-gDCk-e-&zGE#~1A||FcKRE<2%J^SfoFt0YT1_37fmG;)McO>Jq#X#CPX%4uP`_x(Qz+Yaa?ir zQk&u;vT88&DY^X&ZE~B{$`6jZP@gJ2W#F`8aMPH?Q(F|&?6`qJ49NpWM=*%92F@uW zrC}zQw^hLfMUar~&hQ||sDUxGkhFrxE^}OBD4!pliP4`F`Av~0WF)sN7{vvWf>#g#+ zK!<(VMeR;yJBx_Lb!sv7U7RTOsOTgRcbTpo48*ybVRDo2tNJs_3>R@e z?(Q<(I~aNY`z`5kl$6F%A%D8MQ|qY5GkU}?5WobX2G}8*7zgK=#583z+S3f2m@V}t cF-N|Z*7KB4mF(@3y$g#FFJ+gojQcSE04JQNivR!s literal 1987 zcmaJ?T~`}b6x|m>CZq$D@R`yARj8prBYvA;E8)Y&28s=(V*DDCOBj;O#Fd!KV|{(gCK24D%#HFOB{JYCsL@|TxR zQ#u+#0@n|Wrje`~Ryp~2_dpgsf$*YfncjVY&cw{NKxo-6$tXI}t)mNJfxet+$&E&B zS2|n9ZdD4za(2=?DYU93niiUAC(U`OaIk)7G@MjT@rZnV+O zAG)5b>9~noq-r>M+fC}c=i z@xP}diMNUE$f7ixOw!F3_C>t{2&%5(opy2jbVQNBdph372LvihPsyw#ohf9L=_4H< zBPGyHQ%+iCZ{M$(Y!nMvR3UxBYbqqh6obG6CE}+7cdlZ2nRpBxc%ZPBb*!imBJ`6v z^rWktuj%*<4_PhTTq>0u=`snUiB=92$t;JKC9Q6JuH%skS25YN9hOM~>nh9*fmlVi~kf2Y?R^t5lWlRL-_5je7brzY9BU7q<@U@`~dZlN7vi>5IMEf><`H z)x7D+bYB>I5!3|6$$T<+EGMfbp9_m`)TC`qs{Brh2yB6CPl5(3rPRg`EU(q#zRd-N z&svsrmaB&ANJ2e;W-oqVFeb`h-RFh`B6B)@{+uDi#G z{NbCU9F>`yxW-X$&2{u})s0^C5#&1OAzJzsjCjNw-Q4-Lf26*6ih-T6V+^hLhwxWq z<4=r^onRa|!W*YZ?99)f9pi2)G#3vYVg3{gJ8JT7ry4&zMmp8S8}Y6a-1o1j*%FWn z$HPa+q%;K)*W%ilI=`xh>@jkw$Xq;fgvY=C^MYY?LXpV$LGlj_5r*E)_b!SF&Sptr zfwol!{{(|5U|AZU(h18V*UkB89HqTWEKVu6|NxcV6Y~vZl7(g9g zVuyZbY59tXA)=>w^Bam-z%;()EKD!s_>Si^;)n4)EfE;Rq{J^VAv6qVJkyCH_c~C5 abs6oCi2n;=#^ay> diff --git a/src/TCP/TCPClientGUI.java b/src/TCP/TCPClientGUI.java new file mode 100644 index 0000000..8e5d2d2 --- /dev/null +++ b/src/TCP/TCPClientGUI.java @@ -0,0 +1,163 @@ +package TCP; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.*; +import java.io.*; +import java.net.*; + +public class TCPClientGUI extends JFrame { + private JTextField hostField; + private JSpinner portSpinner; + private JTextArea messageArea; + private JTextField inputField; + private JButton connectButton; + private JButton sendButton; + private Socket socket; + private PrintWriter out; + private BufferedReader in; + private boolean connected = false; + + public TCPClientGUI() { + super("TCP Client GUI"); + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + setSize(600, 500); + setLocationRelativeTo(null); + + // Create components + JPanel topPanel = new JPanel(new GridBagLayout()); + GridBagConstraints gbc = new GridBagConstraints(); + gbc.insets = new Insets(5, 5, 5, 5); + gbc.anchor = GridBagConstraints.WEST; + + topPanel.add(new JLabel("Host:"), gbc); + gbc.gridx = 1; + gbc.weightx = 1.0; + gbc.fill = GridBagConstraints.HORIZONTAL; + hostField = new JTextField("localhost", 15); + topPanel.add(hostField, gbc); + + gbc.gridx = 2; + gbc.weightx = 0; + gbc.fill = GridBagConstraints.NONE; + topPanel.add(new JLabel("Port:"), gbc); + gbc.gridx = 3; + portSpinner = new JSpinner(new SpinnerNumberModel(5000, 1, 65535, 1)); + topPanel.add(portSpinner, gbc); + + gbc.gridx = 4; + connectButton = new JButton("Connect"); + connectButton.addActionListener(e -> toggleConnection()); + topPanel.add(connectButton, gbc); + + // Message display area + messageArea = new JTextArea(); + messageArea.setEditable(false); + messageArea.setFont(new Font("Monospaced", Font.PLAIN, 12)); + JScrollPane scrollPane = new JScrollPane(messageArea); + scrollPane.setPreferredSize(new Dimension(0, 300)); + + // Input panel + JPanel inputPanel = new JPanel(new BorderLayout()); + inputField = new JTextField(); + inputField.setEnabled(false); + inputField.addActionListener(e -> sendMessage()); + sendButton = new JButton("Send"); + sendButton.setEnabled(false); + sendButton.addActionListener(e -> sendMessage()); + + inputPanel.add(inputField, BorderLayout.CENTER); + inputPanel.add(sendButton, BorderLayout.EAST); + + // Layout + setLayout(new BorderLayout()); + add(topPanel, BorderLayout.NORTH); + add(scrollPane, BorderLayout.CENTER); + add(inputPanel, BorderLayout.SOUTH); + + setVisible(true); + } + + private void toggleConnection() { + if (!connected) { + connect(); + } else { + disconnect(); + } + } + + private void connect() { + String host = hostField.getText().trim(); + int port = (Integer) portSpinner.getValue(); + + try { + socket = new Socket(host, port); + out = new PrintWriter(socket.getOutputStream(), true); + in = new BufferedReader(new InputStreamReader(socket.getInputStream())); + + connected = true; + connectButton.setText("Disconnect"); + inputField.setEnabled(true); + sendButton.setEnabled(true); + hostField.setEnabled(false); + portSpinner.setEnabled(false); + messageArea.append("Connected to server at " + host + ":" + port + "\n"); + + // Start reader thread + new Thread(this::readFromServer).start(); + + } catch (IOException e) { + JOptionPane.showMessageDialog(this, "Failed to connect: " + e.getMessage(), + "Connection Error", JOptionPane.ERROR_MESSAGE); + disconnect(); + } + } + + private void disconnect() { + connected = false; + connectButton.setText("Connect"); + inputField.setEnabled(false); + sendButton.setEnabled(false); + hostField.setEnabled(true); + portSpinner.setEnabled(true); + messageArea.append("Disconnected from server\n"); + + try { + if (socket != null && !socket.isClosed()) { + socket.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + private void readFromServer() { + String line; + try { + while (connected && (line = in.readLine()) != null) { + String finalLine = line; + SwingUtilities.invokeLater(() -> messageArea.append("Server: " + finalLine + "\n")); + } + } catch (IOException e) { + if (connected) { + SwingUtilities.invokeLater(() -> { + messageArea.append("Connection lost: " + e.getMessage() + "\n"); + disconnect(); + }); + } + } + } + + private void sendMessage() { + String message = inputField.getText().trim(); + if (!message.isEmpty() && connected) { + out.println(message); + messageArea.append("You: " + message + "\n"); + inputField.setText(""); + } + } + + public static void main(String[] args) { + SwingUtilities.invokeLater(TCPClientGUI::new); + } +} diff --git a/src/TCP/TCPServerGUI.java b/src/TCP/TCPServerGUI.java new file mode 100644 index 0000000..405b02f --- /dev/null +++ b/src/TCP/TCPServerGUI.java @@ -0,0 +1,133 @@ +package TCP; + +import javax.swing.*; +import java.awt.*; +import java.io.*; +import java.net.*; +import java.util.concurrent.atomic.AtomicBoolean; + +public class TCPServerGUI extends JFrame { + private JSpinner portSpinner; + private JButton startButton; + private JTextArea logArea; + private ServerSocket serverSocket; + private AtomicBoolean running = new AtomicBoolean(false); + + public TCPServerGUI() { + super("TCP Server GUI"); + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + setSize(600, 500); + setLocationRelativeTo(null); + + // Top panel with port and start button + JPanel topPanel = new JPanel(new FlowLayout(FlowLayout.LEFT)); + topPanel.add(new JLabel("Port:")); + portSpinner = new JSpinner(new SpinnerNumberModel(5000, 1, 65535, 1)); + topPanel.add(portSpinner); + startButton = new JButton("Start Server"); + startButton.addActionListener(e -> toggleServer()); + topPanel.add(startButton); + + // Log area + logArea = new JTextArea(); + logArea.setEditable(false); + logArea.setFont(new Font("Monospaced", Font.PLAIN, 12)); + JScrollPane scrollPane = new JScrollPane(logArea); + + // Layout + setLayout(new BorderLayout()); + add(topPanel, BorderLayout.NORTH); + add(scrollPane, BorderLayout.CENTER); + + setVisible(true); + } + + private void toggleServer() { + if (!running.get()) { + startServer(); + } else { + stopServer(); + } + } + + private void startServer() { + int port = (Integer) portSpinner.getValue(); + try { + serverSocket = new ServerSocket(port); + running.set(true); + startButton.setText("Stop Server"); + portSpinner.setEnabled(false); + logArea.append("TCP Server started on port " + port + "\n"); + + // Accept clients in a separate thread + new Thread(this::acceptClients).start(); + + } catch (IOException e) { + JOptionPane.showMessageDialog(this, "Failed to start server: " + e.getMessage(), + "Server Error", JOptionPane.ERROR_MESSAGE); + stopServer(); + } + } + + private void acceptClients() { + while (running.get()) { + try { + Socket clientSocket = serverSocket.accept(); + logArea.append("Client connected: " + clientSocket.getInetAddress() + "\n"); + + // Handle each client in a separate thread + new Thread(() -> handleClient(clientSocket)).start(); + + } catch (IOException e) { + if (running.get()) { + logArea.append("Error accepting client: " + e.getMessage() + "\n"); + } + } + } + } + + private void handleClient(Socket clientSocket) { + try (BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); + PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true)) { + + String message; + while ((message = in.readLine()) != null) { + String finalMessage = message; + SwingUtilities.invokeLater(() -> + logArea.append("Received from " + clientSocket.getInetAddress() + ": " + finalMessage + "\n")); + + String response = "Echo: " + message; + out.println(response); + } + + } catch (IOException e) { + SwingUtilities.invokeLater(() -> + logArea.append("Client disconnected: " + clientSocket.getInetAddress() + "\n")); + } finally { + try { + clientSocket.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + private void stopServer() { + running.set(false); + startButton.setText("Start Server"); + portSpinner.setEnabled(true); + logArea.append("TCP Server stopped\n"); + + try { + if (serverSocket != null && !serverSocket.isClosed()) { + serverSocket.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + public static void main(String[] args) { + SwingUtilities.invokeLater(TCPServerGUI::new); + } +} diff --git a/src/UDP/UDPClientGUI.java b/src/UDP/UDPClientGUI.java new file mode 100644 index 0000000..8bb0af7 --- /dev/null +++ b/src/UDP/UDPClientGUI.java @@ -0,0 +1,172 @@ +package UDP; + +import javax.swing.*; +import java.awt.*; +import java.io.IOException; +import java.net.*; + +public class UDPClientGUI extends JFrame { + private JTextField hostField; + private JSpinner portSpinner; + private JTextArea messageArea; + private JTextField inputField; + private JButton connectButton; + private JButton sendButton; + private DatagramSocket socket; + private InetAddress address; + private boolean connected = false; + private int port; + private String host; + + public UDPClientGUI() { + super("UDP Client GUI"); + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + setSize(600, 500); + setLocationRelativeTo(null); + + // Create components + JPanel topPanel = new JPanel(new GridBagLayout()); + GridBagConstraints gbc = new GridBagConstraints(); + gbc.insets = new Insets(5, 5, 5, 5); + gbc.anchor = GridBagConstraints.WEST; + + topPanel.add(new JLabel("Host:"), gbc); + gbc.gridx = 1; + gbc.weightx = 1.0; + gbc.fill = GridBagConstraints.HORIZONTAL; + hostField = new JTextField("localhost", 15); + topPanel.add(hostField, gbc); + + gbc.gridx = 2; + gbc.weightx = 0; + gbc.fill = GridBagConstraints.NONE; + topPanel.add(new JLabel("Port:"), gbc); + gbc.gridx = 3; + portSpinner = new JSpinner(new SpinnerNumberModel(6000, 1, 65535, 1)); + topPanel.add(portSpinner, gbc); + + gbc.gridx = 4; + connectButton = new JButton("Connect"); + connectButton.addActionListener(e -> toggleConnection()); + topPanel.add(connectButton, gbc); + + // Message display area + messageArea = new JTextArea(); + messageArea.setEditable(false); + messageArea.setFont(new Font("Monospaced", Font.PLAIN, 12)); + JScrollPane scrollPane = new JScrollPane(messageArea); + scrollPane.setPreferredSize(new Dimension(0, 300)); + + // Input panel + JPanel inputPanel = new JPanel(new BorderLayout()); + inputField = new JTextField(); + inputField.setEnabled(false); + inputField.addActionListener(e -> sendMessage()); + sendButton = new JButton("Send"); + sendButton.setEnabled(false); + sendButton.addActionListener(e -> sendMessage()); + + inputPanel.add(inputField, BorderLayout.CENTER); + inputPanel.add(sendButton, BorderLayout.EAST); + + // Layout + setLayout(new BorderLayout()); + add(topPanel, BorderLayout.NORTH); + add(scrollPane, BorderLayout.CENTER); + add(inputPanel, BorderLayout.SOUTH); + + setVisible(true); + } + + private void toggleConnection() { + if (!connected) { + connect(); + } else { + disconnect(); + } + } + + private void connect() { + host = hostField.getText().trim(); + port = (Integer) portSpinner.getValue(); + + try { + address = InetAddress.getByName(host); + socket = new DatagramSocket(); + socket.setSoTimeout(5000); // 5 second timeout for receiving + + connected = true; + connectButton.setText("Disconnect"); + inputField.setEnabled(true); + sendButton.setEnabled(true); + hostField.setEnabled(false); + portSpinner.setEnabled(false); + messageArea.append("Connected to UDP server at " + host + ":" + port + "\n"); + + // Start reader thread + new Thread(this::readFromServer).start(); + + } catch (UnknownHostException e) { + JOptionPane.showMessageDialog(this, "Unknown host: " + host, + "Connection Error", JOptionPane.ERROR_MESSAGE); + } catch (SocketException e) { + JOptionPane.showMessageDialog(this, "Failed to create socket: " + e.getMessage(), + "Connection Error", JOptionPane.ERROR_MESSAGE); + } + } + + private void disconnect() { + connected = false; + connectButton.setText("Connect"); + inputField.setEnabled(false); + sendButton.setEnabled(false); + hostField.setEnabled(true); + portSpinner.setEnabled(true); + messageArea.append("Disconnected from server\n"); + + if (socket != null && !socket.isClosed()) { + socket.close(); + } + } + + private void readFromServer() { + byte[] buffer = new byte[1024]; + while (connected) { + try { + DatagramPacket receivePacket = new DatagramPacket(buffer, buffer.length); + socket.receive(receivePacket); + String response = new String(receivePacket.getData(), 0, receivePacket.getLength()); + SwingUtilities.invokeLater(() -> messageArea.append("Server: " + response + "\n")); + } catch (SocketTimeoutException e) { + // Timeout is expected, just continue listening + } catch (IOException e) { + if (connected) { + SwingUtilities.invokeLater(() -> { + messageArea.append("Error receiving: " + e.getMessage() + "\n"); + disconnect(); + }); + } + } + } + } + + private void sendMessage() { + String message = inputField.getText().trim(); + if (!message.isEmpty() && connected) { + try { + byte[] data = message.getBytes(); + DatagramPacket sendPacket = new DatagramPacket(data, data.length, address, port); + socket.send(sendPacket); + messageArea.append("You: " + message + "\n"); + inputField.setText(""); + } catch (IOException e) { + JOptionPane.showMessageDialog(this, "Failed to send: " + e.getMessage(), + "Send Error", JOptionPane.ERROR_MESSAGE); + } + } + } + + public static void main(String[] args) { + SwingUtilities.invokeLater(UDPClientGUI::new); + } +} diff --git a/src/UDP/UDPServerGUI.java b/src/UDP/UDPServerGUI.java new file mode 100644 index 0000000..96c43bd --- /dev/null +++ b/src/UDP/UDPServerGUI.java @@ -0,0 +1,120 @@ +package UDP; + +import javax.swing.*; +import java.awt.*; +import java.io.IOException; +import java.net.*; +import java.util.concurrent.atomic.AtomicBoolean; + +public class UDPServerGUI extends JFrame { + private JSpinner portSpinner; + private JButton startButton; + private JTextArea logArea; + private DatagramSocket socket; + private AtomicBoolean running = new AtomicBoolean(false); + + public UDPServerGUI() { + super("UDP Server GUI"); + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + setSize(600, 500); + setLocationRelativeTo(null); + + // Top panel with port and start button + JPanel topPanel = new JPanel(new FlowLayout(FlowLayout.LEFT)); + topPanel.add(new JLabel("Port:")); + portSpinner = new JSpinner(new SpinnerNumberModel(6000, 1, 65535, 1)); + topPanel.add(portSpinner); + startButton = new JButton("Start Server"); + startButton.addActionListener(e -> toggleServer()); + topPanel.add(startButton); + + // Log area + logArea = new JTextArea(); + logArea.setEditable(false); + logArea.setFont(new Font("Monospaced", Font.PLAIN, 12)); + JScrollPane scrollPane = new JScrollPane(logArea); + + // Layout + setLayout(new BorderLayout()); + add(topPanel, BorderLayout.NORTH); + add(scrollPane, BorderLayout.CENTER); + + setVisible(true); + } + + private void toggleServer() { + if (!running.get()) { + startServer(); + } else { + stopServer(); + } + } + + private void startServer() { + int port = (Integer) portSpinner.getValue(); + try { + socket = new DatagramSocket(port); + running.set(true); + startButton.setText("Stop Server"); + portSpinner.setEnabled(false); + logArea.append("UDP Server started on port " + port + "\n"); + + // Listen for packets in a separate thread + new Thread(this::listenForPackets).start(); + + } catch (SocketException e) { + JOptionPane.showMessageDialog(this, "Failed to start server: " + e.getMessage(), + "Server Error", JOptionPane.ERROR_MESSAGE); + stopServer(); + } + } + + private void listenForPackets() { + byte[] buffer = new byte[1024]; + while (running.get()) { + try { + DatagramPacket packet = new DatagramPacket(buffer, buffer.length); + socket.receive(packet); // blocks until packet arrives + + String received = new String(packet.getData(), 0, packet.getLength()); + InetAddress clientAddress = packet.getAddress(); + int clientPort = packet.getPort(); + + SwingUtilities.invokeLater(() -> + logArea.append("Received from " + clientAddress + ":" + clientPort + ": " + received + "\n")); + + // Send response back to sender + String response = "Echo: " + received; + byte[] responseData = response.getBytes(); + DatagramPacket responsePacket = new DatagramPacket( + responseData, responseData.length, + clientAddress, clientPort); + socket.send(responsePacket); + + SwingUtilities.invokeLater(() -> + logArea.append("Sent echo to " + clientAddress + ":" + clientPort + "\n")); + + } catch (IOException e) { + if (running.get()) { + SwingUtilities.invokeLater(() -> + logArea.append("Error: " + e.getMessage() + "\n")); + } + } + } + } + + private void stopServer() { + running.set(false); + startButton.setText("Start Server"); + portSpinner.setEnabled(true); + logArea.append("UDP Server stopped\n"); + + if (socket != null && !socket.isClosed()) { + socket.close(); + } + } + + public static void main(String[] args) { + SwingUtilities.invokeLater(UDPServerGUI::new); + } +}