您的位置:首页 > 理论基础 > 计算机网络

Java Socket 编程——多线程网络聊天程序

2009-12-06 20:05 555 查看
java进行网络编程确实很方便,很容易上手。这几天用java进行socket编程,收获不少。

首先,进行服务端的编程,作为服务端,编程主要按下面几个步骤进行:

// 1. 创建socket

ServerSocket ss = new ServerSocket(PortNumber);

Socket s = ss.accept(); //监听器,产生阻塞,直到有连接才停止阻塞。

// 2. 打开输入流、输出流

OutputStream s = s.getOutputStream();

BufferedOutputStream bos = new BufferedOutputStream(os);

InputStream is = s.getInputStream();

// 3. 根据一定的协议读写数据

//服务器--> 客户

//os.write("Hello,I am Server!".getBytes());

bos.write("Hello,I am Server!".getBytes());

bos.flush(); //注意!!

//服务器<-- 客户

byte[] buf = new byte[100];

int len = is.read(buf);

System.out.println(new String(buf, 0, len));

// 4. 关系流和Socket

//os.close();

bos.close();

is.close();

s.close();

ss.close();

作为客户端则分为下面几个步骤,其实和服务端差不多,只是少了用ServerSocket进行监听。

// 1. 创建socket

Socket s = new Socket(InetAddress.getByName("localhost"),

PortNumber);

// 2. 打开输入流、输出流

OutputStream s = s.getOutputStream();

InputStream is = s.getInputStream();

// 3. 根据一定的协议读写数据

// 服务器 --> 客户

byte[] buf = new byte[100];

int len = is.read(buf);

System.out.println(new String(buf, 0, len));

// 服务器 <-- 客户

os.write("Hello,I am Client!".getBytes());

// 4. 关系流和Socket

os.close();

is.close();

s.close();

上面这些只是一个单线程的服务端->客户端的程序,只能进行一次通讯,多次通讯将被告知无法连接。

这时,我们就需要用到进程Thread进行编程,将其改造成多线程聊天程序,可以同时进行多客户端的连接与发送信息。

代码如下:

//Server.java

import java.awt.*;

import java.net.*;

import java.io.*;

public class Server extends Thread {

ServerSocket skt;

Socket Client[]=new Socket[10];;

Socket Client1=null;

int i = 0;

TextArea in;

int port,k=0,l=0;

//BufferedReader theInputStream;

PrintStream theOutputStream;

//String readin;

Face chat;

public Server(int port, Face chat) {

try {

this.port = port;

skt = new ServerSocket(port);

this.chat = chat;

} catch (IOException e) {

chat.ta.append(e.toString());

}

}

public void run() {

chat.ta.append("等待连线......");

while (true) {

//System.out.print(""+i+"/n");

try {

Client[k] = skt.accept(); /* 接收客户连接 */

//当有客户端连接时就新建一个子线程

if (i < 2) {

ServerThread server[] = new ServerThread[10];

server[k]= new ServerThread(Client[k], this.chat, i);

l=server.length;

server[k].start();

chat.ta.append("客户端" + Client[k].getInetAddress() + "已连线/n");

/*theInputStream = new BufferedReader(new InputStreamReader(Client

.getInputStream()));*/

//for(int j=0;j<server.length;j++)

theOutputStream = new PrintStream(server[k].getClient().getOutputStream());

i = server[k].getI();

k++;

} else {

//theOutputStream = new PrintStream(null);

}

} catch (SocketException e) {

//chat.ta.append("连线中断!/n");

//chat.clientBtn.setEnabled(true);

//chat.serverBtn.setEnabled(true);

//chat.tfaddress.setEnabled(true);

//chat.tfport.setEnabled(true);

//try {

//skt.close();

//Client.close();

//} catch (IOException err) {

// chat.ta.append(err.toString());

//}

} catch (IOException e) {

chat.ta.append(e.toString());

}

}

}

public void dataout(String data) {

//for(int j=0;j<l;j++)

theOutputStream.println(data);

}

}

class ServerThread extends Thread {

ServerSocket skt;

Socket Client;

TextArea in;

int port;

int i;

BufferedReader theInputStream;

PrintStream theOutputStream;

String readin;

Face chat;

//服务端子线程

public ServerThread(Socket s, Face chat, int i) {

this.i = ++i;

Client = s;

//this.port = port;

//skt = new ServerSocket(port);

this.chat = chat;

}

public int getI() {

return this.i;

}

public Socket getClient() {

return this.Client;

}

public void run() {

//chat.ta.append("等待连线......");

try {

//Client = skt.accept(); /* 接收客户连接 */

//chat.ta.append("客户端" + Client.getInetAddress() + "已连线/n");

theInputStream = new BufferedReader(new InputStreamReader(Client

.getInputStream()));

theOutputStream = new PrintStream(Client.getOutputStream());

while (true) {

readin = theInputStream.readLine();

chat.ta.append(readin + "/n");

}

} catch (SocketException e) {

chat.ta.append("连线中断!/n");

chat.clientBtn.setEnabled(true);

chat.serverBtn.setEnabled(true);

chat.tfaddress.setEnabled(true);

chat.tfport.setEnabled(true);

try {

i--;

skt.close();

Client.close();

} catch (IOException err) {

chat.ta.append(err.toString());

}

} catch (IOException e) {

chat.ta.append(e.toString());

}

}

public void dataout(String data) {

theOutputStream.println(data);

}

}

//Client.java

import java.net.*;

import java.io.*;

import javax.swing.Timer;

class Client extends Thread {

Socket skt;

InetAddress host;

int port;

BufferedReader theInputStream;

PrintStream theOutputStream;

String readin;

Face chat;

public Client(String ip, int p, Face chat) {

try {

host = InetAddress.getByName(ip);

port = p;

this.chat = chat;

} catch (IOException e) {

chat.ta.append(e.toString());

}

}

public void run() {

try {

chat.ta.append("尝试连线......");

skt = new Socket(host, port);

chat.ta.append("连线成功/n");

theInputStream = new BufferedReader(new InputStreamReader(skt

.getInputStream()));

theOutputStream = new PrintStream(skt.getOutputStream());

//Timer myTimer = new Timer();

while (true) {

readin = theInputStream.readLine();

chat.ta.append(readin + "/n");

}

} catch (SocketException e) {

chat.ta.append("连线中断!/n");

chat.clientBtn.setEnabled(true);

chat.serverBtn.setEnabled(true);

chat.tfaddress.setEnabled(true);

chat.tfport.setEnabled(true);

try {

skt.close();

} catch (IOException err) {

chat.ta.append(err.toString());

}

} catch (IOException e) {

chat.ta.append(e.toString());

}

}

public void dataout(String data) {

theOutputStream.println(data);

}

}

//软件界面,进行按键监听调用。

//face.java

import java.awt.*;

import java.awt.event.*;

public class Face extends Frame. {

/**

*

*/

private static final long serialVersionUID = 1L;

Button clientBtn, serverBtn;

TextArea ta;

TextField tfaddress, tfport, tftype;

int port;

Client client;

Server server;

boolean iamserver;

static Face frm;

public Face() {

clientBtn = new Button("客户端");

serverBtn = new Button("服务器");

ta = new TextArea("", 10, 50, TextArea.SCROLLBARS_BOTH);

tfaddress = new TextField("192.168.1.104", 20);

tfport = new TextField("2000");

tftype = new TextField(50);

tftype.addKeyListener(new TFListener());

ta.setEditable(false);

setLayout(new FlowLayout());

add(tfaddress);

add(tfport);

add(clientBtn);

add(serverBtn);

add(ta);

add(tftype);

setSize(400, 300);

setTitle("我的聊天室");

this.setVisible(true);

clientBtn.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {

port = Integer.parseInt(tfport.getText());

client = new Client(tfaddress.getText(), port, frm);

client.start();

tfaddress.setEnabled(false);

tfport.setEnabled(false);

serverBtn.setEnabled(false);

clientBtn.setEnabled(false);

}

});

serverBtn.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {

port = Integer.parseInt(tfport.getText());

server = new Server(port, frm);

server.start();

iamserver = true;

tfaddress.setText("成为服务器");

tfaddress.setEnabled(false);

tfport.setEnabled(false);

serverBtn.setEnabled(false);

clientBtn.setEnabled(false);

}

});

addWindowListener(new WindowAdapter() {

public void windowClosing(WindowEvent e) {

System.exit(0);

}

});

}

public static void main(String args[]) {

frm = new Face();

}

private class TFListener implements KeyListener {

public void keyPressed(KeyEvent e) {

if (e.getKeyCode() == KeyEvent.VK_ENTER) {

ta.append(">" + tftype.getText() + "/n");

if (iamserver)

server.dataout(tftype.getText());

else

client.dataout(tftype.getText());

tftype.setText("");

}

}

public void keyTyped(KeyEvent e) {

}

public void keyReleased(KeyEvent e) {

}

}

}

这个程序限制了连接数,可以根据自己的需要进行修改
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: