一、题目
实现客户端与服务端互聊
二、步骤
建立连接:
- 服务端开启8085端口,并监听着,时刻等待着客户端的连接请求
- 客户端知道服务端的ip地址和监听端口号,发出请求到服务端
客户端的端口地址是系统分配的,通常都会大于1024
一旦建立了连接,服务端会得到一个新的Socket对象,该对象负责与客户端进行通信。
注意: 在开发调试的过程中,如果修改过了服务器Server代码,要关闭启动的Server,否则新的Server不能启动,因为8085端口被占用了
收发内容:
一旦建立了连接,服务端和客户端就可以通过Socket进行通信了 - 客户端打开输出流,并发送数字 110
- 服务端打开输入流,接受数字 110,并打印
收发字符串:
直接使用字节流收发字符串比较麻烦,使用数据流对字节流进行封装,这样收发字符串就容易了 - 把输出流封装在DataOutputStream中
使用writeUTF发送字符串 “Legendary!” - 把输入流封装在DataInputStream
使用readUTF读取字符串,并打印
使用Scanner:
在上个步骤中,每次要发不同的数据都需要修改代码
可以使用Scanner读取控制台的输入,并发送到服务端,这样每次都可以发送不同的数据了。
三、实现代码
服务端:Server类
package socketTest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
//服务端
public class Server {
private ServerSocket serverSocket;
private Socket socket;
public Server() {
try {
serverSocket=new ServerSocket(8085);//ServerSocket向操作系统申请8085的端口
System.out.println("服务端等待客户端连接..........");
//服务端在阻塞的过程中,一旦有客户端连接上就会返回一个Socket实例(对象)
socket=serverSocket.accept();//服务端阻塞
System.out.println("有一个客户端已经连接上了服务端");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
Server server=new Server();
server.start();
}
private void start() {
//可以通过socket 与客户端进行交互
try {
while(true) {
//获取输入流
InputStream ips = socket.getInputStream();
InputStreamReader isr=new InputStreamReader(ips,"utf-8");
BufferedReader br=new BufferedReader(isr);
//System.out.println(222222);
//读取数据
String str="";
while((str=br.readLine())!=null) {
//System.out.println(3333);
System.out.println("客户端说:"+str);
Scanner sn=new Scanner(System.in);
//得到输出流
OutputStream os = socket.getOutputStream();
OutputStreamWriter osw=new OutputStreamWriter(os,"utf-8");
PrintWriter pw=new PrintWriter(osw,true);
String msg=sn.next();
pw.println(msg);
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
客户端:Client类
package socketTest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
//客户端
public class Client {
private Socket clientSocket;
//构造方法
public Client() {
try {
System.out.println("客户端正在尝试连接服务端.......");
clientSocket=new Socket("localhost",8085);
System.out.println("已经成功连接8085的服务端");
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//主函数
public static void main(String[] args) {
Client client=new Client();
client.start();
}
private void start() {
System.out.println("客户端:");
//Socket 封装了ip地址 ,io流
try {
while(true) {
//通过socket获取输出流
OutputStream ops=clientSocket.getOutputStream();
//字符流
OutputStreamWriter osw=new OutputStreamWriter(ops,"utf-8");
// 自动行刷新
PrintWriter pw=new PrintWriter(osw,true);
//写出内容
Scanner sn=new Scanner(System.in);
//接收控制台输入的内容
String message=sn.next();
//System.out.println("message:"+message);
pw.println(message);
//获取输入流
InputStream ips = clientSocket.getInputStream();
InputStreamReader isr=new InputStreamReader(ips,"utf-8");
BufferedReader br=new BufferedReader(isr);
String str=br.readLine();
System.out.println("服务端 说:"+str);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
截图:
使用线程实现客户端与服务端互聊的办法:
/*
*
*客户端上的代码
*
*/
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
public class Client {
public static void main(String[] args) {
Thread thread1=new Thread(){
public void run()
{
try {
ServerSocket ss = new ServerSocket(8888);
System.out.println("监听在端口号:8888");
Socket s = ss.accept();
DataInputStream dis=null;
while(true){
InputStream is = s.getInputStream();
//把输入流封装在DataInputStream
dis = new DataInputStream(is);
//使用readUTF读取字符串
String msg = dis.readUTF();
System.out.println(msg);
if(msg==null)
break;
}
dis.close();
s.close();
ss.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
thread1.start();
Thread thread2=new Thread(){
public void run()
{
try {
Socket s = new Socket("192.168.128.128", 8889);//此处放服务器的ip地址
OutputStream os = s.getOutputStream();
DataOutputStream dos = new DataOutputStream(os);
//使用Scanner读取控制台的输入,并发送到服务端
Scanner sc = new Scanner(System.in);
while(true)
{
String str = sc.next();
dos.writeUTF(str);
if(str=="\n")
break;
}
dos.close();
s.close();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
thread2.start();
}
}
/*
*服务器代码
*
*/
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
public class Server {
public static void main(String[] args) {
Thread thread1=new Thread(){
public void run()
{
try {
ServerSocket ss = new ServerSocket(8889);
System.out.println("监听在端口号:8889");
Socket s = ss.accept();
DataInputStream dis=null;
while(true){
InputStream is = s.getInputStream();
//把输入流封装在DataInputStream
dis = new DataInputStream(is);
//使用readUTF读取字符串
String msg = dis.readUTF();
System.out.println(msg);
if(msg==null)
break;
}
dis.close();
s.close();
ss.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
thread1.start();
Thread thread2=new Thread(){
public void run()
{
try {
Socket s = new Socket("192.168.***,***", 8888);//此处放客户端地址
OutputStream os = s.getOutputStream();
DataOutputStream dos = new DataOutputStream(os);
//使用Scanner读取控制台的输入,并发送到服务端
Scanner sc = new Scanner(System.in);
while(true)
{
String str = sc.next();
dos.writeUTF(str);
if(str=="\n")
break;
}
dos.close();
s.close();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
thread2.start();
}
}