在java网络编程中实现服务器和客户端一对一的聊天
2015-10-14 15:30
691 查看
如果有多个客户端接入,都可以发送消息给服务器,但服务器只和最后一个客户聊天。,如果要实现群聊的话,只要把所有的socket保存到集合中,有客户输入时遍历socket得到输出流并把消息广播给各个客户端就行了。
四个读写的线程类都是一样的,可以进行封装,这里就不封装了。
Server服务器主程序
package server;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
private ServerSocket serversocket;
//构造方法
public Server() {
try {
// 得到服务器套接字
serversocket = new ServerSocket(8888);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void start() {
try {
while (true) {
// 等待客户端接入,并通过 套接字得到socket
Socket socket = serversocket.accept();
System.out.println("有客户接入了");
new Thread(new ServerReaderThread(socket)).start();
new Thread(new ServerWriterThread(socket)).start();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
Server server = new Server();
server.start();
}
}
服务器专门用来读用户数据的线程类
ServerReaderThread
package server;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
public class ServerReaderThread implements Runnable{
private Socket socket;
private BufferedReader bf;
private PrintWriter pw;
public ServerReaderThread(Socket socket){
this.socket = socket;
}
@Override
public void run() {
// TODO Auto-generated method stub
// 得到输入和输出流
InputStream is;
try {
is = socket.getInputStream();
OutputStream os = socket.getOutputStream();
// 包装流
bf = new BufferedReader(new InputStreamReader(is));
pw = new PrintWriter(os);
//循环读取客户端输入的数据
while(true){
//读取一行数据
String info = bf.readLine();
System.out.println(info);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
服务器专门用来发送数据给客户的线程类
ServerWriterThread
package server;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
public class ServerWriterThread implements Runnable{
private Socket socket;
private BufferedReader bf;
private PrintWriter pw;
public ServerWriterThread(Socket socket){
this.socket = socket;
}
@Override
public void run() {
// TODO Auto-generated method stub
// 得到输入和输出流
InputStream is;
try {
is = socket.getInputStream();
OutputStream os = socket.getOutputStream();
// 包装流
bf = new BufferedReader(new InputStreamReader(is));
pw = new PrintWriter(os);
Scanner sc = new Scanner(System.in);
//循环读取服务器输入的数据并发送给客户端
while(true){
//读取一行数据
String info = sc.nextLine();
pw.println(info);
pw.flush();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Client 客户端主程序
package client;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Client {
private Socket socket;
// 构造方法
public Client() {
try {
// 得到连接到服务器的socket
socket = new Socket("localhost", 8888);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void start() {
// 等待客户端接入,并通过 套接字得到socket
new Thread(new ClientReaderThread(socket)).start();
new Thread(new ClientWriterThread(socket)).start();
}
public static void main(String[] args) {
Client client = new Client();
client.start();
}
}
客户端用来读取数据的线程类
ClientReaderThread
package client;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
public class ClientReaderThread implements Runnable {
private Socket socket;
private BufferedReader bf;
private PrintWriter pw;
public ClientReaderThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
// TODO Auto-generated method stub
// 得到输入和输出流
InputStream is;
try {
is = socket.getInputStream();
OutputStream os = socket.getOutputStream();
// 包装流
bf = new BufferedReader(new InputStreamReader(is));
pw = new PrintWriter(os);
// 循环读取客户端输入的数据
while (true) {
// 读取一行数据
String info = bf.readLine();
System.out.println(info);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
客户端用来发送消息的线程类
ClientWriterThread
package client;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
public class ClientWriterThread implements Runnable {
private Socket socket;
private BufferedReader bf;
private PrintWriter pw;
public ClientWriterThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
// TODO Auto-generated method stub
// 得到输入和输出流
InputStream is;
try {
is = socket.getInputStream();
OutputStream os = socket.getOutputStream();
// 包装流
bf = new BufferedReader(new InputStreamReader(is));
pw = new PrintWriter(os);
Scanner sc = new Scanner(System.in);
// 循环读取服务器输入的数据并发送给客户端
while (true) {
// 读取一行数据
String info = sc.nextLine();
pw.println(info);
pw.flush();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
四个读写的线程类都是一样的,可以进行封装,这里就不封装了。
Server服务器主程序
package server;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
private ServerSocket serversocket;
//构造方法
public Server() {
try {
// 得到服务器套接字
serversocket = new ServerSocket(8888);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void start() {
try {
while (true) {
// 等待客户端接入,并通过 套接字得到socket
Socket socket = serversocket.accept();
System.out.println("有客户接入了");
new Thread(new ServerReaderThread(socket)).start();
new Thread(new ServerWriterThread(socket)).start();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
Server server = new Server();
server.start();
}
}
服务器专门用来读用户数据的线程类
ServerReaderThread
package server;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
public class ServerReaderThread implements Runnable{
private Socket socket;
private BufferedReader bf;
private PrintWriter pw;
public ServerReaderThread(Socket socket){
this.socket = socket;
}
@Override
public void run() {
// TODO Auto-generated method stub
// 得到输入和输出流
InputStream is;
try {
is = socket.getInputStream();
OutputStream os = socket.getOutputStream();
// 包装流
bf = new BufferedReader(new InputStreamReader(is));
pw = new PrintWriter(os);
//循环读取客户端输入的数据
while(true){
//读取一行数据
String info = bf.readLine();
System.out.println(info);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
服务器专门用来发送数据给客户的线程类
ServerWriterThread
package server;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
public class ServerWriterThread implements Runnable{
private Socket socket;
private BufferedReader bf;
private PrintWriter pw;
public ServerWriterThread(Socket socket){
this.socket = socket;
}
@Override
public void run() {
// TODO Auto-generated method stub
// 得到输入和输出流
InputStream is;
try {
is = socket.getInputStream();
OutputStream os = socket.getOutputStream();
// 包装流
bf = new BufferedReader(new InputStreamReader(is));
pw = new PrintWriter(os);
Scanner sc = new Scanner(System.in);
//循环读取服务器输入的数据并发送给客户端
while(true){
//读取一行数据
String info = sc.nextLine();
pw.println(info);
pw.flush();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Client 客户端主程序
package client;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Client {
private Socket socket;
// 构造方法
public Client() {
try {
// 得到连接到服务器的socket
socket = new Socket("localhost", 8888);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void start() {
// 等待客户端接入,并通过 套接字得到socket
new Thread(new ClientReaderThread(socket)).start();
new Thread(new ClientWriterThread(socket)).start();
}
public static void main(String[] args) {
Client client = new Client();
client.start();
}
}
客户端用来读取数据的线程类
ClientReaderThread
package client;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
public class ClientReaderThread implements Runnable {
private Socket socket;
private BufferedReader bf;
private PrintWriter pw;
public ClientReaderThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
// TODO Auto-generated method stub
// 得到输入和输出流
InputStream is;
try {
is = socket.getInputStream();
OutputStream os = socket.getOutputStream();
// 包装流
bf = new BufferedReader(new InputStreamReader(is));
pw = new PrintWriter(os);
// 循环读取客户端输入的数据
while (true) {
// 读取一行数据
String info = bf.readLine();
System.out.println(info);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
客户端用来发送消息的线程类
ClientWriterThread
package client;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
public class ClientWriterThread implements Runnable {
private Socket socket;
private BufferedReader bf;
private PrintWriter pw;
public ClientWriterThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
// TODO Auto-generated method stub
// 得到输入和输出流
InputStream is;
try {
is = socket.getInputStream();
OutputStream os = socket.getOutputStream();
// 包装流
bf = new BufferedReader(new InputStreamReader(is));
pw = new PrintWriter(os);
Scanner sc = new Scanner(System.in);
// 循环读取服务器输入的数据并发送给客户端
while (true) {
// 读取一行数据
String info = sc.nextLine();
pw.println(info);
pw.flush();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
相关文章推荐
- Android中间httpclient发送帧get求
- HttpClient异常总结
- 《UNIX网络编程》读书笔记1---简介和TCP/IP
- 一种基于浏览器内核修改的复杂网站layout/渲染bug的HTTP重放调试系统
- http://www.cnblogs.com/AloneSword/p/3821569.html
- 网络编码究极入门贴
- NSURLSession类分析
- IOS Android Tomcat SSL双向认证HTTPS访问
- 检测SDWebImage有没有缓存图片 IOS 获取网络图片大小
- WP开发 - HttpWebRequest的GetResponse或GetRequestStream的超时问题
- OSI模型之网络层概述
- Heritrix3.3.0源码阅读 crawler-beans.cxml中处理器链的配置
- 如何解决在Azure上部署Sqlserver网络访问不了
- C++ 用libcurl库进行http通讯网络编程
- SVN服务器迁移,SVN版本库迁移(网络copy)
- 流媒体协议引见(rtp/rtcp/rtsp/rtmp/mms/hls)
- AndroidHttpClient详解及调用示例
- IOS-11-关于AFNetworking访问网络超时的设置
- 20个你可能不知道的 Linux 网络工具
- HTTP/FTP客户端开发库