Java編程實(shí)現(xiàn)基于TCP協(xié)議的Socket聊天室示例
本文實(shí)例講述了Java編程實(shí)現(xiàn)基于TCP協(xié)議的Socket聊天室。分享給大家供大家參考,具體如下:
這里使用Socket套接字進(jìn)行編程,完成的是基于TCP可靠服務(wù)實(shí)現(xiàn)服務(wù)器與客戶端的雙通信。
Server服務(wù)器端:
package com.han;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.*;
import java.net.*;
import javax.swing.JDialog;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
/**
* 本程序?qū)崿F(xiàn)了一個(gè)TCP程序的服務(wù)器編程部分。
* 使用Socket套接字進(jìn)行編程,完成的是基于TCP可靠服務(wù)實(shí)現(xiàn)與客戶端的雙通信。
* 客戶端的編程見(jiàn)本包中的類Client
* @author HAN
*
*/
@SuppressWarnings("serial")
public class Server extends JDialog{
private BufferedReader reader;
private PrintWriter writer;
private ServerSocket server;
private Socket socket;
private JTextArea ta=new JTextArea();
private JScrollPane sp=new JScrollPane(ta);
private JTextField tf=new JTextField();
Container cc;
public Server(String title) {
setTitle(title);
addWindowListener(new WindowAdapter() {
public void windowClosing (WindowEvent we) {
dispose(); //撤銷dialog一切相關(guān)資源
System.exit(0); //正常退出程序
}
});
cc=getContentPane();
setLayout(null);
ta.setLineWrap(true);
ta.setEditable(false);
sp.setBounds(0,0,300,342);
tf.setBounds(0,342,300,25);
cc.add(sp);
cc.add(tf);
tf.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
try {
writer=new PrintWriter(socket.getOutputStream(),true);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
writer.println(tf.getText());
ta.append("User1:"+tf.getText()+'\n');
tf.setText("");
}
});
}
void getserver(){
try{
server=new ServerSocket(8998);
ta.append("服務(wù)器套接字已經(jīng)創(chuàng)建成功\n");
while(true){
ta.append("等待客戶機(jī)的連接\n");
socket=server.accept();
ta.append("客戶機(jī)已連接\n");
reader=new BufferedReader(new InputStreamReader(socket.getInputStream()));
getClientMessage();
}
}catch(Exception e){
e.printStackTrace();
}
}
private void getClientMessage(){
try {
while(true){
String news=reader.readLine();
if(news!=null){
ta.append("User2:"+news+"\n");
}else{
ta.append("User2(客戶端) 已斷開(kāi)鏈接\n");
break;
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try{
if(reader!=null){
reader.close();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(socket!=null){
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Server user1=new Server("User1");
user1.setBounds(0,0,300,400);
user1.setResizable(false);
user1.setVisible(true);
user1.getserver();
}
}
Client客戶端:
package com.han;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import javax.swing.*;
/**
* 本程序?qū)崿F(xiàn)了一個(gè)TCP程序的客戶端編程部分。
* 使用Socket套接字進(jìn)行編程,完成的是基于TCP可靠服務(wù)實(shí)現(xiàn)與服務(wù)器的雙通信。
* 服務(wù)器的編程見(jiàn)本包中的類Server
* 可以在不同的平臺(tái)與不同的機(jī)器上運(yùn)行,只是要把代碼中寫(xiě)的IP地址修改為運(yùn)行服務(wù)器程序Server的機(jī)器的IP地址。
* @author HAN
*
*/
@SuppressWarnings("serial")
public class Client extends JDialog{
private BufferedReader reader;
private PrintWriter writer;
private Socket socket;
private JTextArea ta=new JTextArea();
private JScrollPane sp=new JScrollPane(ta);
private JTextField tf=new JTextField();
Container cc;
public Client(String title) {
setTitle(title);
addWindowListener(new WindowAdapter() {
public void windowClosing (WindowEvent we) {
dispose(); //撤銷dialog一切相關(guān)資源
System.exit(0); //正常退出程序
}
});
cc=getContentPane();
setLayout(null);
ta.setLineWrap(true);
ta.setEditable(false);
sp.setBounds(0,0,300,342);
tf.setBounds(0,342,300,25);
cc.add(sp);
cc.add(tf);
tf.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
writer.println(tf.getText());
ta.append("User2:"+tf.getText()+'\n');
tf.setText("");
}
});
}
private void connect(){
ta.append("嘗試連接\n");
try {
socket=new Socket("192.168.1.3",8998);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
writer=new PrintWriter(socket.getOutputStream(),true);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ta.append("完成連接\n");
}
private void getClientMessage(){
try {
reader=new BufferedReader(new InputStreamReader(socket.getInputStream()));
while(true){
String news=reader.readLine();
if(news!=null){
ta.append("User1:"+news+"\n");
}else{
ta.append("User1(服務(wù)器) 已斷開(kāi)鏈接,等待服務(wù)器重連之時(shí),重啟User2(客戶端)進(jìn)行通信\n");
break;
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
ta.append("User1(服務(wù)器) 已斷開(kāi)鏈接,等待服務(wù)器重連之時(shí),重啟User2(客戶端)進(jìn)行通信\n");
e.printStackTrace();
}
try{
if(reader!=null){
reader.close();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(socket!=null){
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Client user2=new Client("User2");
user2.setBounds(0,0,300,400);
user2.setVisible(true);
user2.setResizable(false);
user2.connect();
user2.getClientMessage();
}
}
更多關(guān)于java相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Java Socket編程技巧總結(jié)》、《Java文件與目錄操作技巧匯總》、《Java數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Java操作DOM節(jié)點(diǎn)技巧總結(jié)》和《Java緩存操作技巧匯總》
希望本文所述對(duì)大家java程序設(shè)計(jì)有所幫助。
相關(guān)文章
簡(jiǎn)單的用java實(shí)現(xiàn)讀/寫(xiě)文本文件的示例
同時(shí)也展示了如果從輸入流中讀出來(lái)內(nèi)容寫(xiě)入輸出流中(僅限文本流) 三個(gè)例子可以獨(dú)立存在,所以根據(jù)需要只看其中一個(gè)就行了。2008-07-07
Spring?Cloud?+?Nacos?+?Seata整合過(guò)程(分布式事務(wù)解決方案)
Seata 是一款開(kāi)源的分布式事務(wù)解決方案,致力于在微服務(wù)架構(gòu)下提供高性能和簡(jiǎn)單易用的分布式事務(wù)服務(wù),這篇文章主要介紹了Spring?Cloud?+?Nacos?+?Seata整合過(guò)程(分布式事務(wù)解決方案),需要的朋友可以參考下2022-03-03
Java實(shí)現(xiàn)軟件運(yùn)行時(shí)啟動(dòng)信息窗口的方法
這篇文章主要介紹了Java實(shí)現(xiàn)軟件運(yùn)行時(shí)啟動(dòng)信息窗口的方法,比較實(shí)用的功能,需要的朋友可以參考下2014-08-08
APP轉(zhuǎn)盤(pán)抽獎(jiǎng)Java服務(wù)端接口詳解
這篇文章主要為大家詳細(xì)介紹了APP轉(zhuǎn)盤(pán)抽獎(jiǎng)Java服務(wù)端接口,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-01-01
springboot+thymeleaf+layui的實(shí)現(xiàn)示例
本文主要介紹了springboot+thymeleaf+layui的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-12-12
解決java項(xiàng)目jar打包后讀取文件失敗的問(wèn)題
這篇文章主要介紹了解決java項(xiàng)目jar打包后讀取文件失敗的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06
Spring Aop組成部分及實(shí)現(xiàn)步驟
面向切面編程,是對(duì)面向?qū)ο缶幊痰囊环N補(bǔ)充,是一種編程思想,是對(duì)某一類的事情的集中處理,這篇文章主要介紹了Spring Aop組成部分及實(shí)現(xiàn)步驟,需要的朋友可以參考下2023-08-08
springboot項(xiàng)目如何使用切面記錄用戶操作日志
這篇文章主要介紹了springboot項(xiàng)目如何使用切面記錄用戶操作日志,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-10-10

