當前位置:編程學習大全網 - 編程語言 - Java套接字編程登錄

Java套接字編程登錄

給妳壹個聊天室,這是客戶端之間的交流,服務器負責接收轉發,妳要的服務器和客戶端是對面的,寫個界面顯示和輸入給服務器就行了。所有代碼如下:

測試的時候要把所有的代碼放在同壹個項目下,因為客戶端可以對服務器使用同壹個POJO,裏面有壹些包錯誤,刪除就好了。

服務器代碼,即服務器門戶程序:

導入Java . io . buffered reader;

導入Java . io . file;

導入Java . io . io exception;

導入Java . io . inputstreamreader;

導入Java . io . object output stream;

導入Java . io . printwriter;

導入Java . net . server socket;

導入Java . net . socket;

導入Java . util . date;

導入Java . util . hashset;

公共類聊天室服務器{

私有服務器套接字ss;

私有HashSet & ltSocket & gtallSockets

private UserDao dao

公共聊天室服務器(){

嘗試{

ss =新服務器套接字(9999);

allSockets = new HashSet & ltSocket & gt();

Dao = new UserDaoForTextFile(new File(" d:/stu/user . txt "));

} catch (IOException e) {

e . printstacktrace();

}

}

public void startService()拋出IOException{

while(true){

socket s = ss . accept();

allSockets.add

新的ChatRoomServerThread。start();

}

}

類ChatRoomServerThread擴展線程{

私有套接字s;

公共聊天室服務器線程(套接字){

this.s = s

}

公共無效運行(){

//1,獲取Socket的輸入流並打包。

//2、從輸入流中循環讀取壹行數據。

//3、每讀取壹行數據,判斷該行是否為退出命令?

//4,如果是退出命令,從集合中刪除當前套接字,關閉當前套接字,跳出循環。

//5,如果不是退出命令,那麽轉發model.getCurrentUser()的註銷信息。getName()發送給所有在線客戶端。

//循環通過allSockets集合獲取每個套接字的輸出流,並將消息寫入流中。

BufferedReader br = null

String str = null

嘗試{

br =新的BufferedReader(新的InputStreamReader

。getInputStream()));

while((str=br.readLine())!=null ){

if(str . index of(" % EXIT % " = = 0){

allSockets.remove

//向其他客戶端發送XXX退出消息。

sendmessage toall client(str . split(":)[1]+"離開聊天室!");

s . close();

打破;

} else if(str . index of(" % log in % " = = 0){

string userName = str . split(":)[1];

string password = str . split(":)[2];

User user=dao.getUser(用戶名,密碼);

object output stream OOS = new object output stream(s . get output stream());

oos.writeObject(用戶);

OOS . flush();

如果(用戶!=null){

sendmessagetoallclient(user . getname()+"進入聊天室!");

}

str = null

}

if(str!=null){

sendMessageToAllClient(str);

}

}

} catch(異常e) {

e . printstacktrace();

}

}

公共void sendMessageToAllClient(字符串消息)引發IOException{

Date Date = new Date();

system . out . println(s . getine address()+":"+message+" \ t["+date+"]");

for(套接字溫度:所有套接字){

PrintWriter pw = new PrintWriter(temps . get output stream());

pw . println(message+" \ t["+date+"]");

pw . flush();

}

}

}

公共靜態void main(String[] args) {

嘗試{

新聊天室服務器()。startService();

} catch (IOException e) {

e . printstacktrace();

}

}

}

客戶代碼:

***總共4個:

1:進入程序:

公共類聊天室客戶端{

私有ClientModel模型;

公共聊天室客戶端(){

//String hostName = joptionpane . showinputdialog(null,

//"請輸入服務器主機名:");

// String portName = JOptionPane

// .showInputDialog(null,“請輸入端口號:“);

//固定服務器IP和端口

model = new client model(" 127 . 0 . 0 . 1 ",integer . parse int(" 9999 "));

model . create socket();

新的LoginFrame(模型)。show me();

}

公共靜態void main(String[] args) {

new chatroom client();

}

}

2.登錄後顯示界面:

導入Java . awt . borderlayout;

導入Java . awt . event . action event;

導入Java . awt . event . action listener;

導入Java . awt . event . window adapter;

導入Java . awt . event . window event;

導入Java . io . buffered reader;

導入Java . io . io exception;

導入Java . io . printwriter;

導入javax . swing . jbutton;

導入javax . swing . jframe;

導入javax . swing . jlabel;

導入javax . swing . joptionpane;

導入javax . swing . jpanel;

導入javax . swing . jscrollpane;

導入javax . swing . jtextarea;

導入javax . swing . jtextfield;

公共類ClientMainFrame擴展JFrame{

私有JTextArea區域;

私有JTextField字段;

私有JLabel標簽;

私有JButton按鈕;

私有ClientModel模型;

公共客戶端主機(){

超級("聊天室客戶端v 1.0 ");

area=new JTextArea(20,40);

field = new JTextField(25);

button = new JButton(" send ");

label = new JLabel();

JScrollPane JSP = new JScrollPane(area);

this.add(jsp,BorderLayout。中心);

JPanel panel = new JPanel();

panel.add(標簽);

panel.add(字段);

panel.add(按鈕);

this.add(panel,BorderLayout。南);

add eventhandler();

}

公共客戶端大型機(ClientModel模型){

this();

this.model = model

label . settext(model . getcurrentuser()。getName());

}

public void addEventHandler(){

action listener lis = new SendEventListener();

button . addactionlistener(lis);

field . addactionlistener(lis);

this . addwindowlistener(new window adapter(){

public void window closing(window event arg 0){

Intop = jooptionpane。showconfirmdiary (null,“您確定要退出聊天室嗎?”,“確認退出”,JOptionPane。YES _ NO _ OPTION);

if(op==JOptionPane。是_選項){

PrintWriter pw = model . get output stream();

if(model.getCurrentUser()。getName()!=null){

pw . println(" % EXIT % "+model . getcurrentuser()。getName());

pw . flush();

}

嘗試{

thread . sleep(200);

} catch(異常e) {

}

system . exit(0);

}

}

});

}

public void showMe(){

this . pack();

this . set visible(true);

this.setLocation(300,300);

this . setdefaultcloseoperation(JFrame。什麽都不做(ON CLOSE);

新的ReadMessageThread()。start();

}

類SendEventListener實現ActionListener{

public void action performed(action event e){

String str=field.getText()。trim();

if(str . equals(" "){

Joptionpane。showmessagedialog (null,“不能發送空消息!”);

返回;

}

PrintWriter pw = model . get output stream();

pw . println(model . getcurrentuser()。getName()+":"+str);

pw . flush();

field . settext(" ");

}

}

類ReadMessageThread擴展線程{

公共無效運行(){

while(true){

嘗試{

buffered reader br = model . getinputstream();

string str = br . readline();

area . append(str+" \ n ");

} catch (IOException e) {

}

}

}

}

}

3.登錄界面:

導入Java . awt . color;

導入Java . awt . dimension;

導入Java . awt . font;

導入Java . awt . point;

導入Java . awt . rectangle;

導入Java . awt . event . action event;

導入Java . awt . event . action listener;

導入Java . awt . event . window adapter;

導入Java . awt . event . window event;

導入Java . io . io exception;

導入Java . io . inputstream;

導入Java . io . objectinputstream;

導入Java . io . printwriter;

導入javax . swing . jbutton;

導入javax . swing . jframe;

導入javax . swing . jlabel;

導入javax . swing . joptionpane;

導入javax . swing . jpanel;

導入javax . swing . jpasswordfield;

導入javax . swing . jtextfield;

公共類LoginFrame擴展JFrame {

private static final long serialVersionUID = 1L;

private JPanel jContentPane = null;

private JLabel lab 1 = null;

private JLabel lab2 = null

private JLabel lab3 = null

private JTextField username field = null;

private JPasswordField password field = null;

private JButton log in button = null;

private JButton register button = null;

private JButton cancel button = null;

private ClientModel模型= null

/**

*此方法初始化userNameField

*

* @return javax.swing.JTextField

*/

private JTextField get username field(){

if (userNameField == null) {

username field = new JTextField();

userNameField.setSize(新維度(171,33));

userNameField.setFont(新字體("對話框",字體。平原,18));

userNameField.setLocation(新點(140,70));

}

返回用戶名字段;

}

/**

*此方法初始化passwordField

*

* @ return javax . swing . jpasswordfield

*/

private JPasswordField getPasswordField(){

if (passwordField == null) {

password field = new JPasswordField();

passwordField.setSize(新維度(173,30));

passwordField.setFont(新字體("對話框",字體。平原,18));

passwordField.setLocation(新點(140,110));

}

返回passwordField

}

/**

*此方法初始化loginButton

*

* @return javax.swing.JButton

*/

私有JButton getLoginButton() {

if (loginButton == null) {

log in button = new JButton();

loginButton.setLocation(新點(25,180));

log in button . settext(" log in ");

loginButton.setSize(新維度(75,30));

}

返回登錄按鈕;

}

/**

*此方法初始化cancelButton

*

* @return javax.swing.JButton

*/

私有JButton getCancelButton() {

if (cancelButton == null) {

cancel button = new JButton();

cancelButton.setLocation(新點(270,180));

cancel button . settext(" cancel ");

cancelButton.setSize(新維度(75,30));

}

返回取消按鈕;

}

/**

*顯示接口的方法,其中調用addEventHandler()方法向組件添加事件偵聽器。

*

*/

public void showMe(){

this . setdefaultcloseoperation(JFrame。什麽都不做(ON CLOSE);

this . set visible(true);

this.setLocation(300,200);

add eventhandler();

}

/**

*此方法用於向組件添加事件監聽。

*

*/

public void addEventHandler(){

action listener log in listener = new LoginEventListener();

log in button . addactionlistener(log in listener);

password field . addactionlistener(log in listener);

cancel button . addactionlistener(new action listener(){

public void action performed(action event e){

嘗試{

model.getSocket()。close();

} catch (IOException e1) {

e 1 . printstacktrace();

}

system . exit(0);

}

});

this . addwindowlistener(new window adapter(){

public void window closing(window event arg 0){

嘗試{

model.getSocket()。close();

} catch (IOException e1) {

e 1 . printstacktrace();

}

system . exit(0);

}

});

}

/**

*這個內部類用於監控登錄事件。

* @作者管理員

*

*/

LoginEventListener類實現ActionListener{

public void action performed(action event e){

//?登錄代碼

//1,判斷用戶名和密碼是否為空。

//2,從clientmodel,PrintWriter獲取輸出流。

//3、向服務器發送登錄請求。

//pw . println(" % log in %:userName:password ");

//4,從socket獲取對象輸入流,從流中讀取壹個對象。

//5.如果讀取的對象為空,則顯示登錄失敗消息。

//6,如果讀取的對象不為空,則將其轉換為用戶對象,並將。

//將clientmodel的currentUser對象設置為此對象。

//7、銷毀當前窗口,打開主界面窗口。

字符串userName = userName field . gettext();

char[]c = password field . get password();

string password = string . value of(c);

if(userName = = null | | userName . equals(" "){

joptionpane . showmessagedialog(null,“用戶名不能為空”);

返回;

}

if(password = = null | | password . equals(" "){

joptionpane . showmessagedialog(null,“密碼名不能為空”);

返回;

}

PrintWriter pw = model . get output stream();

pw . println(" % log in % "+userName+":"+password);

pw . flush();

嘗試{

InputStream is = model.getSocket()。getInputStream();

system . out . println(" is "+is . getclass());

ObjectInputStream ois =新的ObjectInputStream(is);

object obj = ois . read object();

if(obj!= null){

用戶user =(用戶)obj

如果(用戶!= null){

model.setCurrentUser(用戶);

log in frame . this . dispose();

新的客戶端主機(型號)。show me();

}

}

否則{

Joptionpane。顯示消息對話框(空,“用戶名或密碼錯誤,請重新輸入”);

username field . settext(" ");

password field . settext(" ");

返回;

}

} catch(異常e1) {

e 1 . printstacktrace();

}

}

}

公共靜態void main(String[] args) {

新的LoginFrame()。show me();

}

/**

*這是默認的構造函數

*/

公共LoginFrame(ClientModel模型){

this();

this.model = model

}

公共LoginFrame(){

super();

initialize();

}

public ClientModel getModel() {

退貨模式;

}

public void set model(client model model){

this.model = model

}

/**

*此方法初始化此

*

* @返回void

*/

私有void initialize() {

this.setSize(362,267);

this . setcontentpane(getJContentPane());

This.setTitle("達內聊天室-用戶登錄");

}

/**

*此方法初始化jContentPane

*

* @return javax.swing.JPanel

*/

私有JPanel getJContentPane() {

if (jContentPane == null) {

lab 3 = new JLabel();

Lab3.setText("秘密代碼:");

lab3.setSize(新維度(80,30));

lab3.setFont(新字體(“對話框”,字體。粗體,18));

lab3.setLocation(新點(50,110));

lab 2 = new JLabel();

Lab2.setText("用戶名:");

lab2.setSize(新維度(80,30));

lab 2 . settooltiptext(" ");

lab2.setFont(新字體(“對話框”,字體。粗體,18));

lab2.setLocation(新點(50,70));

lab 1 = new JLabel();

lab1.setBounds(新矩形(54,12,245,43));

lab1.setFont(新字體(“對話框”,字體。粗體,24));

lab1.setForeground(新顏色(0,0,204));

Lab1.setText("聊天室-用戶登錄");

jContentPane = new JPanel();

jcontentpane . set layout(null);

jContentPane.add(lab1,null);

jContentPane.add(lab2,null);

jContentPane.add(lab3,null);

jcontentpane . add(get username field(),null);

jcontentpane . add(getPasswordField(),null);

jcontentpane . add(getLoginButton(),null);

jcontentpane . add(getCancelButton(),null);

}

返回jContentPane

}

}

4.客戶端管理套接字類

導入Java . io . buffered reader;

導入Java . io . io exception;

導入Java . io . inputstreamreader;

導入Java . io . printwriter;

導入Java . net . socket;

/**

*該類定義了客戶端的全局參數,如套接字、當前用戶、流對象等。

*

*/

公共類ClientModel {

私用插座插座;

私人用戶currentUser

private BufferedReader br

私人版畫家pw;

私有字符串主機名;

專用int端口;

公共套接字getSocket() {

返回插座;

}

public ClientModel(字符串主機名,int端口){

super();

this.hostName = hostName

this.port = port

}

公共用戶getCurrentUser() {

返回currentUser

}

public void setCurrentUser(User currentUser){

this . current user = current user;

}

公共同步套接字createSocket(){

if(socket==null){

嘗試{

socket =新套接字(主機名,端口);

}catch (IOException e) {

e . printstacktrace();

返回null

}

}

返回插座;

}

public synchronized buffered reader getInputStream(){

if (br==null) {

嘗試{

br =新的BufferedReader(新的InputStreamReader(套接字

。getInputStream()));

} catch (IOException e) {

e . printstacktrace();

返回null

}

}

返回br;

}

公共同步PrintWriter getOutputStream(){

if (pw==null) {

嘗試{

pw = new PrintWriter(socket . get output stream());

} catch (IOException e) {

e . printstacktrace();

返回null

}

}

返回pw;

}

公共同步void closeSocket(){

如果(插座!=null){

嘗試{

br . close();

pw . close();

socket . close();

} catch (IOException e) {

e . printstacktrace();

}

}

socket = null

br = null

pw = null

}

}

以下是工具和POJO類:

用戶類別:

導入Java . io . serializable;

公共類用戶實現可序列化{

private static final long serial version uid = 1986 l;

private int id

私有字符串名稱;

私有字符串密碼;

私人字符串電子郵件;

公共用戶(){}

公共用戶(字符串名稱、字符串密碼、字符串電子郵件){

super();

this.name = name

this.password =密碼;

this.email = email

}

公共用戶(字符串名稱、字符串密碼){

super();

this.name = name

this.password =密碼;

}

public int getId() {

返回id;

}

public void setId(int id) {

this.id = id

}

公共字符串getName() {

返回名稱;

}

public void setName(字符串名){

this.name = name

}

公共字符串getPassword() {

返回密碼;

}

public void setPassword(字符串密碼){

this.password =密碼;

}

公共字符串getEmail() {

回復郵件;

}

public void setEmail(字符串電子郵件){

this.email = email

}

公共字符串toString(){

返回id+":"+姓名+":"+密碼+":"+電子郵件;

}

}

DAO,用於在本地讀取配置文件。

界面:

公共接口UserDao {

public boolean addUser(用戶User);

公共用戶getUser(字符串用戶名,字符串密碼);

}

實現類:

導入Java . io . buffered reader;

導入Java . io . file;

導入Java . io . file inputstream;

導入Java . io . file output stream;

導入Java . io . io exception;

導入Java . io . inputstreamreader;

導入Java . io . printwriter;

公共類UserDaoForTextFile實現UserDao{

私有文件userFile

public UserDaoForTextFile(){

}

public UserDaoForTextFile(File File){

this.userFile = file

如果(!file.exists()){

嘗試{

file . create new file();

} catch (IOException e) {

e . printstacktrace();

}

}

}

公共同步布爾addUser(用戶user) {

FileInputStream fis = null

BufferedReader br = null

int lastId = 0;

嘗試{

fis =新文件輸入流(用戶文件);

br = new BufferedReader(新的InputStreamReader(fis));

String str = null

String lastLine = null

while((str=br.readLine())!= null){

//獲取最後壹行值

lastLine = str

if(str . split(":)[1]。equals(user . getname()){

返回false

}

}

if(lastLine!=空)

lastId = integer . parse int(last line . split(":)[0]);

}catch(異常e){

e . printstacktrace();

}最後{

如果(br!=null)請嘗試{ br . close();}catch(IOException e){}

如果(fis!=null)請嘗試{ fis . close();}catch(IOException e){}

}

FileOutputStream fos = null

PrintWriter pw = null

嘗試{

fos = new file output stream(user file,true);

pw =新的PrintWriter(fos);

user . setid(lastId+1);

pw.println(用戶);

pw . flush();

返回true

}catch(異常e){

e . printstacktrace();

}最後{

如果(pw!=null)請嘗試{ pw . close();}catch(異常e){}

如果(fos!=null)請嘗試{ fos . close();}catch(IOException e){}

}

返回false

}

公共同步用戶getUser(字符串用戶名,字符串密碼){

FileInputStream fis = null

BufferedReader br = null

String str = null

用戶user = null

嘗試{

fis =新文件輸入流(用戶文件);

br = new BufferedReader(新的InputStreamReader(fis));

while((str = br.readLine())!= null){

string[]s = str . split(":");

if(username . equals(s[1])& amp;& amppassword.equals(s[2])){

User = new User();

user . setid(integer . parse int(s[0]));

user . set name(s[1]);

user . set password(s[2]);

user . set email(s[3]);

}

}

}catch(IOException e){

e . printstacktrace();

}最後{

如果(br!=null)請嘗試{ br . close();}catch(IOException e){}

如果(fis!=null)請嘗試{ fis . close();}catch(IOException e){}

}

返回用戶;

}

}

配置文件格式為:

Id序列號:用戶名:密碼:電子郵件地址

1:yawin:034437:yawin @ 126 . com

2:周jg:034437:周@126.com

  • 上一篇:MFC數據庫編程,想設置權限,普通用戶登入比管理員登入顯示的表中數據要少壹些。
  • 下一篇:長方形的體積計算公式
  • copyright 2024編程學習大全網