Socket编程 连接(连接是通过输入输出流来传送数据)
创建服务器
package com.hp.tcp;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
/**
* 服务端
*
* @author 晓电脑
*/
public class Service {
//创建一个容器用于接受每一个连接
private List serviceThreadList=new ArrayList<>();
public static void main(String[] args) throws IOException {
new Service().connect();
}
public void connect() throws IOException {
//创建服务器 指定端口
ServerSocket socket = new ServerSocket(8888);
while (true) {
Socket accept = socket.accept();
ServiceThread thread = new ServiceThread(accept);
serviceThreadList.add(thread);
new Thread(thread).start();
}
}
class ServiceThread implements Runnable {
private DataInputStream stream;
private DataOutputStream outputStream;
private boolean isRuning = true;
private String name;
public ServiceThread() {
}
public ServiceThread(Socket socket) {
try {
//接受客户端的数据的流
stream = new DataInputStream(socket.getInputStream());
//返回客户端数据的流
outputStream = new DataOutputStream(socket.getOutputStream());
this.name = stream.readUTF();
send("欢迎进入聊天室");
sendOthers(name+"进入了聊天室",false);
} catch (IOException e) {
// e.printStackTrace();
CloseUtils.close(stream, outputStream);
isRuning = false;
serviceThreadList.remove(this);
}
}
/**
* 接受客户端数据
*
* @return
*/
public String accept() {
String readUTF = null;
try {
readUTF = stream.readUTF();
} catch (IOException e) {
// e.printStackTrace();
CloseUtils.close(stream);
isRuning = false;
serviceThreadList.remove(this);
}
return readUTF;
}
/**
* 发送客户端数据
*/
public void send(String acept) {
try {
outputStream.writeUTF(acept);
outputStream.flush();
} catch (IOException e) {
// e.printStackTrace();
CloseUtils.close(stream);
isRuning = false;
serviceThreadList.remove(this);
}
}
/**
* 发给其他客户端
*/
public void sendOthers(String accept,boolean flag){
//私聊的实现
if (accept.startsWith("@") && accept.indexOf(":")>-1){
String title=accept.substring(1,accept.indexOf(":"));
String content=accept.substring(accept.indexOf(":")+1);
for (ServiceThread serviceThread : serviceThreadList) {
if (serviceThread.name.equals(title)){
serviceThread.send(this.name+"对你私聊说"+content);
}
}
}else {
for (ServiceThread serviceThread : serviceThreadList) {
if (serviceThread.equals(this))continue;
if (flag){
serviceThread.send(this.name+"对所有人说"+accept);
}else {
serviceThread.send("系统消息"+accept);
}
}
}
}
@Override
public void run() {
while (isRuning){
sendOthers(accept(),true);
}
}
}
}
创建客户端
package com.hp.tcp;
import java.io.*;
import java.net.Socket;
/**客户端
* @author 晓电脑
*/
public class Client {
public static void main (String[] args) throws IOException {
System.out.println("请输入名称");
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String readLine = reader.readLine();
if (readLine == null){
return;
}
//创建客户端 指定服务器
Socket socket = new Socket("localhost",8888);
new Thread(new Send(socket,readLine)).start();
new Thread(new Accept(socket)).start();
}
}
创建发送信息的线程
package com.hp.tcp;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
/**发送消息线程
* @author 晓电脑
*/
public class Send implements Runnable {
private BufferedReader bufferedReader;
private DataOutputStream dataOutputStream;
private boolean isRun=true;
//名称
private String name;
public Send(){
bufferedReader=new BufferedReader(new InputStreamReader(System.in));
}
public Send(Socket socket,String name){
this();
try {
dataOutputStream = new DataOutputStream(socket.getOutputStream());
this.name=name;
send(name);
} catch (IOException e) {
//e.printStackTrace();
isRun=false;
CloseUtils.close(dataOutputStream,bufferedReader);
}
}
/**
* 接受服务器数据
* @return
*/
public String accept(){
String readLine=null;
try {
readLine = bufferedReader.readLine();
} catch (IOException e) {
//e.printStackTrace();
isRun=false;
CloseUtils.close(dataOutputStream,bufferedReader);
}
return readLine;
}
/**
* 发给服务器数据
* @param str
*/
public void send(String str){
try {
dataOutputStream.writeUTF(str);
} catch (IOException e) {
// e.printStackTrace();
isRun=false;
CloseUtils.close(dataOutputStream,bufferedReader);
}
}
@Override
public void run() {
while (isRun){
send(accept());
}
}
}
接受消息线程
package com.hp.tcp;
import java.io.DataInputStream;
import java.io.IOException;
import java.net.Socket;
/**
* 接受的线程
*/
public class Accept implements Runnable {
private DataInputStream dataInputStream;
private boolean isRun=true;
public Accept(){}
public Accept(Socket socket){
try {
this.dataInputStream=new DataInputStream(socket.getInputStream());
} catch (IOException e) {
// e.printStackTrace();
CloseUtils.close(dataInputStream);
isRun=false;
}
}
public void write(){
String str=null;
try {
str=dataInputStream.readUTF();
System.out.println(str);
} catch (IOException e) {
// e.printStackTrace();
CloseUtils.close(dataInputStream);
isRun=false;
}
}
@Override
public void run() {
while (isRun){
write();
}
}
}
群聊运行效果为
在另一个客户端可以接受到
私聊功能的效果
在qwe客户端可以接受到
在另一个客户端是接收不到私聊数据的