1.简单聊天室-客户端给服务器发数据(示例)
客户端:
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.net.UnknownHostException;
public class Client {
public static void main(String[] args) throws UnknownHostException, IOException {
//定义套接字
Socket socket = new Socket("192.168.13.2", 8091);
//使用socket来读写数据
OutputStream outputStream = socket.getOutputStream();
//用起来也不方便,打印流
PrintStream ps = new PrintStream(outputStream);
ps.println("你好。。。");
//关闭资源
ps.flush();
ps.close();
socket.close();
}
}
服务器:
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
/**
* 定义服务器,做为数据的中转中心
* 1.实现客户端给服务器发送数据
* @author igeekhome
*
*/
public class Server {
public static void main(String[] args) throws IOException {
//获取服务器套接字
ServerSocket serverSocket = new ServerSocket(8091);-
//等待客户端连接,会阻塞线程,直到客户端连接,如果客户端连接就会产生并注册一个套接字
Socket socket = serverSocket.accept();
//使用套接字来获取和输出数据,通过流的方式来实现
InputStream inputStream = socket.getInputStream();
//为了方便字节流,使用Scanner来扫描数据
Scanner scanner = new Scanner(inputStream);
//循环获取数据
while(scanner.hasNextLine()) {
String data = scanner.nextLine();
System.out.println(data);
}
//关闭资源
scanner.close();
socket.close();
serverSocket.close();
}
}
2.简单聊天室-实现发送和同时接收【示例】
使用多线程来完成此示例
发送数据线程:
import java.io.IOException;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Scanner;
public class ClientSendThread implements Runnable {
private Socket socket;
private PrintStream ps;
public ClientSendThread(Socket socket) throws IOException {
this.socket = socket;
ps = new PrintStream(socket.getOutputStream());
}
@Override
public void run() {
Scanner sc = new Scanner(System.in);
while(true) {
System.out.println("请输入发送的数据:");
String data = sc.nextLine();
ps.println(data);
}
}
}
接收数据线程:
import java.io.IOException;
import java.net.Socket;
import java.util.Scanner;
/**
* 接收数据的线程,我们肯定需要输入流,从Socket中获取,做为参数传进来
* 打开输入流
* @author igeekhome
*
*/
public class ClientReceiveThread implements Runnable {
private Socket socket;
private Scanner scanner;
public ClientReceiveThread(Socket socket) throws IOException {
this.socket = socket;
scanner = new Scanner(socket.getInputStream());
}
@Override
public void run() {
while(true) {
while(scanner.hasNextLine()) {
String data = scanner.nextLine();
System.out.println("服务器发来的数据:"+data);
}
}
}
}
客户端启动线程:
/**
* 如果客户端既要能够获取用户输入的数据然后发送给服务器,这是我们需要使用Scanner扫描用户输入,但是这个扫描会阻塞线程
* 那么我们还想从套结子中获取服务器写会的数据,就无法实现,因为该操作也要阻塞线程,想要解决这样的问题就需要使用两个独立的线程
* 为了结构清晰,我们尾客户端定义两个子线程,一个线程用来发送数据,一个线程永来接受数据
* @author igeekhome
*
*/
public class Client {
public static void main(String[] args) throws UnknownHostException, IOException {
//定义套接字
Socket socket = new Socket("localhost", 8091);
new Thread(new ClientSendThread(socket)).start();
new Thread(new ClientReceiveThread(socket)).start();
}
}
服务器端做为中转中心:
/**
* 定义服务器,做为数据的中转中心
* 1.实现客户端给服务器发送数据
* @author igeekhome
*
*/
public class Server {
public static void main(String[] args) throws IOException {
//获取服务器套接字
ServerSocket serverSocket = new ServerSocket(8091);
//等待客户端连接,会阻塞线程,直到客户端连接,如果客户端连接就会产生并注册一个套接字
Socket socket = serverSocket.accept();
System.out.println("客户端连接成功");
//使用套接字来获取和输出数据,通过流的方式来实现
InputStream inputStream = socket.getInputStream();
OutputStream outputStream = socket.getOutputStream();
//为了方便字节流,使用Scanner来扫描数据
Scanner scanner = new Scanner(inputStream);
PrintStream ps = new PrintStream(outputStream);
//循环获取数据
while(true) {
while(scanner.hasNextLine()) {
String data = scanner.nextLine();
System.out.println("服务器接受的数据"+ data);
ps.println(data);
}
}
}
}
3.多客户端聊天器【示例】
使用多线程来完成此示例
发送数据线程:
import java.io.IOException;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Scanner;
public class ClientSendThread implements Runnable {
private Socket socket;
private PrintStream ps;
public ClientSendThread(Socket socket) throws IOException {
this.socket = socket;
ps = new PrintStream(socket.getOutputStream());
}
@Override
public void run() {
Scanner sc = new Scanner(System.in);
while(true) {
System.out.println("请输入发送的数据:");
String data = sc.nextLine();
ps.println(data);
}
}
}
接收数据线程:
/**
* 接受数据的线程,我们肯定需要输入流,从Socket中获取,做为参数传进来
* 打开输入流
* @author igeekhome
*
*/
public class ClientReceiveThread implements Runnable {
private Socket socket;
private Scanner scanner;
public ClientReceiveThread(Socket socket) throws IOException {
this.socket = socket;
scanner = new Scanner(socket.getInputStream());
}
@Override
public void run() {
while(true) {
while(scanner.hasNextLine()) {
String data = scanner.nextLine();
System.out.println("服务器发来的数据:"+data);
}
}
}
}
循环读取数据线程:
import java.io.IOException;
import java.io.PrintStream;
import java.net.Socket;
import java.util.List;
import java.util.Scanner;
public class ServerThread implements Runnable{
private Socket socket;
private List<Socket> socketList;
private Scanner scanner;
public ServerThread(Socket socket,List<Socket> socketList) throws IOException {
this.socket = socket;
this.socketList = socketList;
this.scanner = new Scanner(socket.getInputStream());
}
@Override
public void run() {
while(true) {
//如果有数据就读取
while(scanner.hasNextLine()) {
String data = scanner.nextLine();
for(Socket sk : socketList) {
if(sk==socket) {
continue;
}
try {
PrintStream ps = new PrintStream(sk.getOutputStream());
ps.println(data);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}
客户端启动线程:
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.net.UnknownHostException;
/**
* 如果客户端既要能够获取用户输入的数据然后发送给服务器,这是我们需要使用Scanner扫描用户输入,但是这个扫描会阻塞线程
* 那么我们还想从套结子中获取服务器写会的数据,就无法实现,因为该操作也要阻塞线程,想要解决这样的问题就需要使用两个独立的线程
* 为了结构清晰,我们尾客户端定义两个子线程,一个线程用来发送数据,一个线程永来接受数据
* @author igeekhome
*/
public class Client {
public static void main(String[] args) throws UnknownHostException, IOException {
//定义套接字
Socket socket = new Socket("localhost", 8091);
new Thread(new ClientSendThread(socket)).start();
new Thread(new ClientReceiveThread(socket)).start();
}
}
服务器端做为中转中心:
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
/**
* 定义服务器,做为数据的中转中心
* 1.实现客户端给服务器发送数据
* 2.实现获取客户端发来得数据,同时将数据发回客户端
* 3.服务器支持对客户端的连接,accept方法,就可以获取一个客户端的连接,要获取多客户段的操作,就需要存储于多个客户端之间的连接,就是socket
* @author igeekhome
*
*/
public class Server {
private static List<Socket> socketList = new ArrayList<Socket>();
public static void main(String[] args) throws IOException {
//获取服务器套接字
ServerSocket serverSocket = new ServerSocket(8091);
//等待客户端连接,会阻塞线程,直到客户端连接,如果客户端连接就会产生并注册一个套接字,一个客户端连接的操作需要一个独立线程来支持
while(true) {
Socket socket = serverSocket.accept();
socketList.add(socket);
System.out.println("客户端连接成功");
new Thread(new ServerThread(socket, socketList)).start();
}
}
}