基于TCP的Socket编程
单向连接 - 有请求无返回
/**
* 服务器:
* 1.指定端口:使用ServerSocket创建
* 2.阻塞式等待连接 accept
* 3.输入输出流操作
* 4.释放资源
* */
public class TcpServer {
public static void main(String[] args) throws Exception{
ServerSocket server = new ServerSocket(8888);
Socket accept = server.accept();
System.out.println("连接成功");
DataInputStream dis = new DataInputStream(accept.getInputStream());
String s = dis.readUTF();
// 数据操作
System.out.println(s);
dis.close();
accept.close();
}
}
/**
* 客户端:
* 1.建立连接:使用Socket创建客户端 + 服务器的地址和端口
* 2.操作:输入输出流操作
* 3.释放资源
* */
public class TcpClient {
public static void main(String[] args) throws Exception {
Socket client = new Socket("localhost", 8888);
DataOutputStream dos = new DataOutputStream(client.getOutputStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
System.out.println("请输入账号:");
String name = reader.readLine();
System.out.println("请输入密码:");
String pwd = reader.readLine();
dos.writeUTF("name:"+name+"|pwd:"+pwd);
dos.flush();
dos.close();
client.close();
}
}
双向连接 - 一次有请求有返回
/**
* 服务器:
* 1.指定端口:使用ServerSocket创建
* 2.阻塞式等待连接 accept
* 3.输入输出流操作
* 4.释放资源
* */
public class TcpServer {
public static void main(String[] args) throws Exception {
ServerSocket server = new ServerSocket(8888);
Socket accept = server.accept();
System.out.println("连接成功");
DataInputStream dis = new DataInputStream(accept.getInputStream());
String s = dis.readUTF();
System.out.println(s);
// 数据操作
String[] split = s.split("&");
String[] name = split[0].split(":");
String[] pwd = split[1].split(":");
String result = null;
if ("111".equals(name[1]) && "222".equals(pwd[1])) {
result = "验证成功";
}else {
result = "验证失败";
}
DataOutputStream dos = new DataOutputStream(accept.getOutputStream());
dos.writeUTF(result);
dos.flush();
dos.close();
dis.close();
accept.close();
}
}
/**
* 客户端:
* 1.建立连接:使用Socket创建客户端 + 服务器的地址和端口
* 2.操作:输入输出流操作
* 3.释放资源
* */
public class TcpClient {
public static void main(String[] args) throws Exception {
Socket client = new Socket("localhost", 8888);
DataOutputStream dos = new DataOutputStream(client.getOutputStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
System.out.println("请输入账号:");
String name = reader.readLine();
System.out.println("请输入密码:");
String pwd = reader.readLine();
dos.writeUTF("name:"+name+"&pwd:"+pwd);
dos.flush();
DataInputStream dis = new DataInputStream(client.getInputStream());
String result = dis.readUTF();
System.out.println(result);
dis.close();
dos.close();
client.close();
}
}
文件传输
/**
* 服务器:
* 1.指定端口:使用ServerSocket创建
* 2.阻塞式等待连接 accept
* 3.输入输出流操作
* 4.释放资源
* */
public class TcpFileServer {
public static void main(String[] args) throws Exception {
ServerSocket server = new ServerSocket(8888);
Socket accept = server.accept();
System.out.println("连接成功");
InputStream is = new BufferedInputStream(accept.getInputStream());
OutputStream os = new BufferedOutputStream(new FileOutputStream("src/ii.png"));
byte[] bytes = new byte[1024 * 60];
int len = -1;
while ((len = is.read(bytes)) != -1) {
os.write(bytes, 0, len);
}
os.flush();
os.close();
is.close();
accept.close();
}
}
/**
* 客户端:
* 1.建立连接:使用Socket创建客户端 + 服务器的地址和端口
* 2.操作:输入输出流操作
* 3.释放资源
* */
public class TcpFileClient {
public static void main(String[] args) throws Exception {
Socket client = new Socket("localhost", 8888);
InputStream is = new BufferedInputStream(new FileInputStream("src/img.jpg"));
OutputStream os = new BufferedOutputStream(client.getOutputStream());
byte[] bytes = new byte[1024 * 60];
int len = -1;
while ((len=is.read(bytes)) != -1) {
os.write(bytes, 0, len);
}
os.flush();
os.close();
is.close();
client.close();
}
}
多客户端连接
/**
* 服务器:
* 1.指定端口:使用ServerSocket创建
* 2.阻塞式等待连接 accept
* 3.输入输出流操作
* 4.释放资源
* */
public class TcpMultiServer {
public static void main(String[] args) throws Exception{
System.out.println("服务器端:");
ServerSocket server = new ServerSocket(8888);
Integer flag = 0;
boolean isRunning = true;
while (isRunning) {
Socket client = server.accept();
flag ++;
System.out.println(flag + "号客户端连接成功");
new Thread(new OneClient(client)).start();
}
server.close();
}
static class OneClient implements Runnable {
private Socket client;
private DataInputStream dis;
private DataOutputStream dos;
public OneClient(Socket client) {
this.client = client;
try {
dis = new DataInputStream(client.getInputStream());
dos = new DataOutputStream(client.getOutputStream());
} catch (Exception e) {
e.printStackTrace();
release();
}
}
private void release() {
try {
if (null != dos) {
dos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (null != dis) {
dis.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (null != client) {
client.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
private String receive() {
String data = "";
try {
data = dis.readUTF();
} catch (IOException e) {
e.printStackTrace();
}
return data;
}
private void send(String msg) {
try {
dos.writeUTF(msg);
dos.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
String receive = receive();
System.out.println("接收到的数据:");
System.out.println(receive);
Integer s = (int) ((Math.random() * 10) + 1);
System.out.println("随机返回1-10整数:" + s);
send(s.toString());
release();
}
}
}
/**
* 客户端:
* 1.建立连接:使用Socket创建客户端 + 服务器的地址和端口
* 2.操作:输入输出流操作
* 3.释放资源
* */
public class TcpMultiClient {
public static void main(String[] args) throws Exception{
System.out.println("客户端:");
Socket client = new Socket("localhost", 8888);
new Send(client).send();
new Receive(client).receive();
client.close();
}
static class Send {
private Socket client;
private DataOutputStream dos;
private BufferedReader br;
private String msg;
public Send(Socket client) {
this.client = client;
br = new BufferedReader(new InputStreamReader(System.in));
this.msg = init();
try {
dos = new DataOutputStream(client.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
private String init() {
try {
System.out.println("请输入:");
String s = br.readLine();
} catch (IOException e) {
e.printStackTrace();
}
return "";
}
public void send() {
try {
dos.writeUTF(msg);
dos.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
}
static class Receive{
private Socket client;
private DataInputStream dis;
public Receive(Socket client) {
this.client = client;
try {
dis = new DataInputStream(client.getInputStream());
} catch (Exception e) {
e.printStackTrace();
}
}
public void receive() {
String result;
try {
result = dis.readUTF();
System.out.println(result);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
模拟群聊 - 多客户端互发送
/***********************************
*
* @description: 资源释放工具类
*
**********************************/
public class CloseableUtils {
/**
*
* 所有的流都继承自Closeable,可直接通过其关闭资源
* ... - 代表不固定的参
*
* */
public static void close(Closeable... targets) {
for (Closeable target : targets) {
try {
if (null != target) {
target.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
package tcpDemo;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.CopyOnWriteArrayList;
/***********************************
*
* @description: 服务器
*
**********************************/
public class Chat {
private static CopyOnWriteArrayList<Channel> all = new CopyOnWriteArrayList<>();
private static Integer num = 0;
public static void main(String[] args) throws IOException {
System.out.println("------Server------");
ServerSocket server = new ServerSocket(8888);
/* 阻塞式等待连接 */
while (true) {
Socket client = server.accept();
num++;
System.out.println(num + "号客户端连接成功");
Channel channel = new Channel(client);
all.add(channel);
new Thread(channel).start();
}
}
static class Channel implements Runnable {
private DataInputStream dis;
private DataOutputStream dos;
private Socket client;
private boolean isRunning;
private String name;
public Channel(Socket client) {
this.client = client;
try {
dis = new DataInputStream(client.getInputStream());
dos = new DataOutputStream(client.getOutputStream());
isRunning = true;
this.name = receive();
sendOther(this.name + "已上线", true);
} catch (IOException e) {
e.printStackTrace();
release();
}
}
/* 接收消息 */
private String receive() {
String msg = "";
try {
msg = dis.readUTF();
} catch (Exception e) {
e.printStackTrace();
release();
}
return msg;
}
/* 发送消息 */
private void send(String msg) {
try {
dos.writeUTF(msg);
dos.flush();
} catch (IOException e) {
e.printStackTrace();
release();
}
}
/* 发送消息给其他client */
private void sendOther(String msg, boolean isSys) {
for (Channel other : all) {
if (other == this) {
continue;
}
if (isSys) {
other.send(msg);
}else {
other.send(this.name + ":" + msg);
}
}
}
/* 释放资源 */
private void release() {
this.isRunning = false;
// 关闭资源
CloseableUtils.close(dis, dos, client);
// 退出
all.remove(this);
sendOther(this.name + "已下线", true);
}
@Override
public void run() {
while (isRunning) {
String msg = receive();
if (!msg.equals("")) {
sendOther(msg, false);
}
}
}
}
}
package tcpDemo;
import java.io.*;
import java.net.Socket;
/***********************************
*
* @description: 客户端
*
**********************************/
public class Client {
public static void main(String[] args) throws IOException {
System.out.println("------Client------");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("请输入用户名:");
String name = br.readLine();
Socket client = new Socket("127.0.0.1", 8888);
new Thread(new Send(client, name)).start();
new Thread(new Receive(client)).start();
}
}
/* 接收 */
class Receive implements Runnable {
private DataInputStream dis;
private Socket client;
private boolean isRunning;
public Receive(Socket client) {
this.client = client;
this.isRunning = true;
try {
dis = new DataInputStream(client.getInputStream());
} catch (IOException e) {
e.printStackTrace();
release();
}
}
private String receive() {
String msg = "";
try {
msg = dis.readUTF();
} catch (IOException e) {
e.printStackTrace();
release();
}
return msg;
}
private void release() {
this.isRunning = false;
CloseableUtils.close(dis, client);
}
@Override
public void run() {
while (isRunning) {
String msg = receive();
if (!msg.equals("")) {
System.out.println(msg);
}
}
}
}
class Send implements Runnable {
private DataOutputStream dos;
private BufferedReader br;
private Socket client;
private boolean isRunning;
private String name;
public Send(Socket client, String name) {
this.client = client;
this.isRunning = true;
this.name = name;
br = new BufferedReader(new InputStreamReader(System.in));
try {
dos = new DataOutputStream(client.getOutputStream());
send(name);
} catch (IOException e) {
e.printStackTrace();
release();
}
}
private void send(String msg) {
try {
dos.writeUTF(msg);
dos.flush();
} catch (IOException e) {
e.printStackTrace();
release();
}
}
private String getStrFormConsole() {
String msg = "";
try {
msg = br.readLine();
} catch (IOException e) {
e.printStackTrace();
}
return msg;
}
private void release() {
this.isRunning = false;
CloseableUtils.close(dos, client);
}
@Override
public void run() {
while (isRunning) {
String msg = getStrFormConsole();
if(!msg.equals("")) {
send(msg);
}
}
}
}