TcpServer
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.security.Provider;
import java.util.*;
public class TcpServer {
//创建 一个客服端的集合 之后会遍历
public static List<Client_channel> list = new ArrayList<Client_channel>();
public static List<File_server> list2 = new ArrayList<File_server>();
//定义两个端口
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(8888);
ServerSocket serverSocket1 = new ServerSocket(8889);
//用于发送文件的端口
while(true){
Socket socket = serverSocket.accept();
System.out.println("现在有一个线程进来了!!");
Socket socket1= serverSocket1.accept();
Client_channel client_channel = new Client_channel(socket);
list.add(client_channel);
File_server file_server = new File_server(socket1);
list2.add(file_server);
new Thread(client_channel).start();
new Thread(file_server).start();
}
}
}
File_serve
/*
用于服务器进行收发文件线程的操作
*/
import java.io.*;
import java.net.Socket;
import java.security.AccessControlException;
import java.util.List;
public class File_server implements Runnable {
public DataInputStream Input;
public DataOutputStream output;
private boolean flag=true;
private BufferedReader bf;
private PrintWriter pw;
private int number;
private Socket socket;
public File_server(Socket socket){
// init
this.socket= socket;
try {
Input = new DataInputStream(this.socket.getInputStream());
output = new DataOutputStream(this.socket.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
TcpServer.list2.remove(this);
}
//传入对象
}
@Override
public void run() {
try{
while(true){
// 需要接收文件的大小
String textName = Input.readUTF();
long textLength = Input.readLong();
for( int i =0;i<TcpServer.list2.size();i++){
if(TcpServer.list2.get(i).equals(this)){
continue;
}
else {
TcpServer.list2.get(i).output.writeUTF(textName);
TcpServer.list2.get(i).output.flush();
TcpServer.list2.get(i).output.writeLong(textLength);
TcpServer.list2.get(i).output.flush();
}
}
// 发送内容
int length = -1;
long curLength =0;
byte [] buff = new byte [1024];
while((length = Input.read(buff))>0){
curLength+=length;
for( int i =0;i<TcpServer.list2.size();i++){
if(TcpServer.list2.get(i).equals(this)){
continue;
}
else {
//发送内容
TcpServer.list2.get(i).output.write(buff,0,length);
TcpServer.list2.get(i).output.flush();
}
}
if(curLength==textLength){
break;
}
}
}
}
catch (Exception e){
TcpServer.list2.remove(this);
}
}
}
Client_sta
public class Client_sta {
public static int number=0;
public static void main(String[] args) {
for( int i =0;i<3;i++){
new client(i);
}
}
}
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.net.Socket;
public class client extends JFrame implements ActionListener,Runnable
{
public int number;
// 利用number 存储文件名
private JTextArea jTextArea;
private JPanel jPanel;
private JButton jb;
public Socket file_socket;
private JButton jb_file;
private JScrollPane jScrollPane;
private JTextField jTextField;
private DataOutputStream dos;
private Send send;
public Socket socket;
private Filesend filesend;
private Thread thread;
public client ( int number){
super("my_chat");
//通信相关
this.number=number;
try {
this.socket= new Socket("127.0.0.1",8888);
this.file_socket= new Socket("127.0.0.1",8889);
this.filesend = new Filesend(this);
//申请不同的端口号
this.dos= new DataOutputStream(this.socket.getOutputStream());
this.send= new Send(this.socket);
//this.receive= new Receive(this.socket);
} catch (IOException e) {
JOptionPane.showMessageDialog(this,"连接不到服务器");
}
this.jTextArea= new JTextArea();
this.jTextField= new JTextField(10);
this.jScrollPane= new JScrollPane(this.jTextArea);
this.jb= new JButton("send");
this.jb_file= new JButton("send_file");
this.jb_file.addActionListener(this); //this 处理
//发送文件按钮
this.jPanel= new JPanel();
//添加组件
this.getContentPane().setLayout( new BorderLayout());
this.getContentPane().add(this.jScrollPane,BorderLayout.CENTER);
this.getContentPane().add(this.jPanel,BorderLayout.SOUTH);
this.jPanel.add(this.jTextField);
this.jPanel.add(this.jb); this.jPanel.add(this.jb_file);
this.jb.addActionListener(this); //由this对象处理
//位置
this.setLocationRelativeTo(null);
this.setBounds(200,400, 400,200);
this.setResizable(false);
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
this.setVisible(true);
new Thread(this).start();
new Thread(this.filesend).start();
}
// 对于这个问题而言 只要点击按钮就是发送数据
@Override
public void actionPerformed(ActionEvent actionEvent) {
if(actionEvent.getSource().equals(this.jb)) {
String str = this.jTextField.getText();
System.out.println("现在发送 的是"+str);
if (str == "") {
JOptionPane.showMessageDialog(this, "不能为空!!");
} else {
Send.str=str;
new Thread(this.send).start();
this.jTextArea.append("\n" + "me say :" + str);
System.out.println("正在发送数据!!");
//点击发送之后发送线程启动
}
}
// 函数的调用 发送文件
if(actionEvent.getSource().equals(this.jb_file)){
// 提示查看文件的目录 ,在控制台输出提示信息 。
System.out.println("文件成功传输! ,在文件中查看!");
String str = this.jTextField.getText();
this.filesend.send_file(str);
// 做一个线程跑接受文件 这个线程的功能就是发送文件 ,接受文件
}
}
@Override
public void run() {
System.out.println("客服端正在接受数据!!!");
DataInputStream inputStream;
BufferedReader bf;
try {
inputStream = new DataInputStream(socket.getInputStream());
BufferedReader buffer = new BufferedReader(new InputStreamReader(inputStream));
//
String s=null;
while((s=buffer.readLine())!=null){ //应该是会阻塞自己的
System.out.println("收到了"+s);
this.jTextArea.append("\n"+s);
}
} catch (IOException e) {
}
}
}
Filesend
import javax.swing.*;
import java.io.*;
import java.net.Socket;
/*
用于客服端发送接收文件
*/
public class Filesend implements Runnable {
// 接受、发送文件
private File file;
private DataOutputStream fileWriter ;
private DataInputStream fileReader;
private DataInputStream file_in;
private DataOutputStream file_out;
private String filename;
private client my_client;
private Socket socket;
private File userFile;
public Filesend(client c){
this.my_client=c;
try {
this.socket=this.my_client.file_socket;
this.file_in= new DataInputStream(socket.getInputStream());
this.file_out= new DataOutputStream(socket.getOutputStream());
this.userFile= new File("D:\\idea socket\\"+this.my_client.number);
} catch (FileNotFoundException e) {
JOptionPane.showMessageDialog(this.my_client,"请检查文件是不是存在!!");
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
//发送文件只是发送一次即可
public void send_file(String str){
// 如果是重新进行套接字的连接的话 ,发送文件
this.file = new File(str);
try{
this.fileReader= new DataInputStream(new FileInputStream(file));
file_out.writeUTF(file.getName());
file_out.flush();
file_out.writeLong(file.length());
file_out.flush();
int length=-1;
byte [] buff = new byte[1024];
while((length=fileReader.read(buff))>0){
file_out.write(buff,0,length);
file_out.flush();
}
}catch (IOException e){
e.printStackTrace();
}
}
@Override
public void run(){
//客服端如何进行接受呢 ? 这是个问题
// 重新设置套接字吗 服务器怎么区分数据
try {
while(true) {
String textName = file_in.readUTF(); //文件名称
long Length = file_in.readLong(); //文件长度
int result = JOptionPane.showConfirmDialog(this.my_client, "是不是接收文件?", "提示", JOptionPane.YES_NO_CANCEL_OPTION);
int len = -1;
byte[] buff = new byte[1024];
long curLength = 0;
if (result == 0) {
// 接收文件
if(!userFile.exists()){
userFile.mkdir(); //不存在的话创建文件目录
}
this.file= new File("D:\\idea socket\\"+this.my_client.number+"\\"+textName);
System.out.println(this.my_client.number+"文件号码");
// 接收文件
fileWriter = new DataOutputStream(new FileOutputStream(file));
//文件输出
while((len=file_in.read(buff))>0){
fileWriter.write(buff,0,len); //写入本地
fileWriter.flush();
curLength+=len;
if(curLength==Length){
break;
// 直接结束
}
}
}
//不接受文件
else {
while ((len=file_in.read(buff))>0){
curLength +=len;
if(curLength== Length){
break;
}
}
}
fileWriter.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Send
import java.io.*;
import java.net.Socket;
/*
发送线程 因为不会只接一次
*/
public class Send implements Runnable {
public static String str;
public BufferedReader bf;
public DataOutputStream dos ;
private PrintWriter pw;
private boolean flag = true;
public Send(Socket socket){
try {
this.dos= new DataOutputStream(socket.getOutputStream());
this.pw= new PrintWriter(this.dos);
} catch (IOException e) {
e.printStackTrace();
}
}
public String my_send(String str){
String a= null;
try {
//this.dos.writeUTF(str);
pw.println(str);
pw.flush();
//this.dos.flush();
} catch (Exception e) {
this.flag=false;
try {
this.dos.close();
//清空缓冲区
} catch (IOException ex) {
ex.printStackTrace();
}
}
return a ;
}
//收发进程
@Override
public void run() {
//一直在发送 直到this.flag
System.out.println("客服端正发送"+str);
this.my_send(Send.str);
//
}
public void close(){
try{
this.dos.close();
}catch (Exception e){
e.printStackTrace();
}
}
}
Client_channel
/*
1.输入流
2.输出流
3.发送数据
4.接收数据
*/
import javax.swing.*;
import java.io.*;
import java.net.Socket;
import java.util.List;
public class Client_channel implements Runnable {
private DataInputStream dataInputStream;
private DataOutputStream dataOutputStream;
private boolean flag=true;
private BufferedReader bf;
private PrintWriter pw;
private int number;
private Socket socket;
// 构造方法
public Client_channel(Socket socket) {
try{
number=0;
this.socket=socket;
dataInputStream= new DataInputStream(socket.getInputStream());
dataOutputStream = new DataOutputStream(socket.getOutputStream());
this.bf= new BufferedReader(new InputStreamReader(dataInputStream));
this.pw= new PrintWriter(this.dataOutputStream);
//输入流
}
catch (IOException e){
this.flag= false;
try {
this.dataOutputStream.close();
this.dataInputStream.close();
} catch (IOException ex) {
System.out.println("create 中出错!!");
}
}
}
public int getPort(){
return this.socket.getPort();
}
/*
//receive 数据
private String receive() {
String str="";
try {
str= dataInputStream.readUTF();
System.out.println("我收到了"+str);
} catch (IOException e) {
this.flag= false;
// 关闭dataInputStream
try {
this.dataInputStream.close();
}
catch (IOException ex) {
ex.printStackTrace();
}
TcpServer.list.remove(this);
// 关闭dataInputStream
}
return str;
}
*/
// send
private void send( String str){
if(str!=""&&str.length()!=0){
try {
this.pw.println(str);
this.pw.flush();
System.out.println("now the function send 发送"+str);
//将缓冲区中 的东西强制送出去 防止数据收不到的情况。
} catch (Exception e) {
this.flag=false;
//e.printStackTrace();
}
}
}
// 给别的进程发送数据
private void send_other(String str) {
System.out.println(" send_other :现在是转发给别的线程" + str);
List<Client_channel> list = TcpServer.list;
//
synchronized ( list) {
for (int i = 0; i < list.size(); i++) {
System.out.println("Port is :"+list.get(i).getPort());
if (list.get(i).equals(this)) {
continue;
}
list.get(i).send(str);
}
}
}
@Override
public void run() {
while (true) {
try {
String s= bf.readLine();
if(s!=null)
//线程会阻塞
{
this.send_other(s);
}
// 一直监听线程发送的内容
} catch (Exception e) {
System.out.println("客服端断开连接!!");
break;
}
}
}
}