Javaは全二重クロストーク通信を実現する。


「Java利用によるクロストーク全二重通信」蒋清野更新。
更新1:ソースコードから返された文字数が送信された文字数よりも遅れているバグを修正します。
更新2:javax.comのバグを修正します。このBUGはjava BlackBoxとして常にNo serial portfoundに戻ります。
注:更新箇所にudate by LZAを表示します。
 
環境:Win 7  + JDK 1.7+Java Communications API 2.0(commm.jar)
 
ReadSerial.java
//package serial;
import java.io.*;

/**
 * 
 * This class reads message from the specific serial port and save the message
 * to the serial buffer.
 * 
 */
public class ReadSerial extends Thread {
	private SerialBuffer ComBuffer;
	private InputStream ComPort;

	/**
	 * 
	 * Constructor
	 * 
	 * @param SB
	 *            The buffer to save the incoming messages.
	 * @param Port
	 *            The InputStream from the specific serial port.
	 * 
	 */
	public ReadSerial(SerialBuffer SB, InputStream Port) {
		ComBuffer = SB;
		ComPort = Port;
	}

	public void run() {
		int c;
		try {
			while (true) {
				c = ComPort.read();
				ComBuffer.PutChar(c);
			}
		} catch (IOException e) {
		}
	}
}
 
SerialBean.java
//package serial;
import java.io.*;
import java.util.*;
import javax.comm.*;

/**
 * 
 * This bean provides some basic functions to implement full dulplex information
 * exchange through the srial port.
 * 
 */
public class SerialBean {
	static String PortName;
	CommPortIdentifier portId;
	SerialPort serialPort;
	static OutputStream out;
	static InputStream in;
	SerialBuffer SB;
	ReadSerial RT;

	/**
	 * 
	 * Constructor
	 * 
	 * @param PortID
	 *            the ID of the serial to be used. 1 for COM1, 2 for COM2, etc.
	 * 
	 */
	public SerialBean(int PortID) {
		PortName = "COM" + PortID;
	}

	/**
	 * 
	 * This function initialize the serial port for communication. It startss a
	 * thread which consistently monitors the serial port. Any signal capturred
	 * from the serial port is stored into a buffer area.
	 * 
	 */
	public int Initialize() {
		int InitSuccess = 1;
		int InitFail = -1;
		try {
			portId = CommPortIdentifier.getPortIdentifier(PortName);
			try {
				serialPort = (SerialPort) portId.open("Serial_Communication",
						2000);
			} catch (PortInUseException e) {
				return InitFail;
			}
			// Use InputStream in to read from the serial port, and OutputStream
			// out to write to the serial port.
			try {
				in = serialPort.getInputStream();
				out = serialPort.getOutputStream();
			} catch (IOException e) {
				return InitFail;
			}
			// Initialize the communication parameters to 9600, 8, 1, none.
			try {
				serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8,
						SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
			} catch (UnsupportedCommOperationException e) {
				return InitFail;
			}
		} catch (NoSuchPortException e) {
			return InitFail;
		}
		// when successfully open the serial port, create a new serial buffer,
		// then create a thread that consistently accepts incoming signals from
		// the serial port. Incoming signals are stored in the serial buffer.
		SB = new SerialBuffer();
		RT = new ReadSerial(SB, in);
		RT.start();
		// return success information
		return InitSuccess;
	}

	/**
	 * 
	 * This function returns a string with a certain length from the incomin
	 * messages.
	 * 
	 * @param Length
	 *            The length of the string to be returned.
	 * 
	 */
	public String ReadPort(int Length) {
		String Msg;
		Msg = SB.GetMsg(Length);
		return Msg;
	}

	/**
	 * 
	 * This function sends a message through the serial port.
	 * 
	 * @param Msg
	 *            The string to be sent.
	 * 
	 */
	public void WritePort(String Msg) {
		int c;
		try {
			for (int i = 0; i < Msg.length(); i++)
				out.write(Msg.charAt(i));
		} catch (IOException e) {
		}
	}

	/**
	 * 
	 * This function closes the serial port in use.
	 * 
	 */
	public void ClosePort() {
		RT.stop();
		serialPort.close();
	}
}
 
SerialBuffer.java
//package serial;
/**
 * 
 * This class implements the buffer area to store incoming data from the serial
 * port.
 * 
 */
public class SerialBuffer {
	private String Content = "";
	private String CurrentMsg, TempContent;
	private boolean available = false;
	private int LengthNeeded = 1;

	/**
	 * 
	 * This function returns a string with a certain length from the incomin
	 * messages.
	 * 
	 * @param Length
	 *            The length of the string to be returned.
	 * 
	 */
	public synchronized String GetMsg(int Length) {
		LengthNeeded = Length;
		notifyAll();
		if (LengthNeeded > Content.length()) {
			available = false;
			while (available == false) {
				try {
					wait();
				} catch (InterruptedException e) {
				}
			}
		}
		CurrentMsg = Content.substring(0, LengthNeeded);
		TempContent = Content.substring(LengthNeeded);
		Content = TempContent;
		LengthNeeded = 1;
		notifyAll();
		return CurrentMsg;
	}

	/**
	 * 
	 * This function stores a character captured from the serial port to the
	 * buffer area.
	 * 
	 * @param t
	 *            The char value of the character to be stored.
	 * 
	 */
	public synchronized void PutChar(int c) {
		Character d = new Character((char) c);
		Content = Content.concat(d.toString());
		if (LengthNeeded <= Content.length()) // update by LZA
		{
			available = true;
		}
		notifyAll();
	}
}
 
SerialExample.java
import java.io.*;
import java.util.*;
import javax.comm.*;
import com.sun.comm.*;

class SerialExample {
	public static void main(String[] args) {
		// update by LZA

		Win32Driver w32Driver = new Win32Driver();
		//      javax.comm BUG

		w32Driver.initialize();
		//        ,        port

		// TO DO: Add your JAVA codes here
		SerialBean SB = new SerialBean(1);
		String Msg;
		SB.Initialize();
		for (int i = 5; i <= 10; i++) {
			Msg = SB.ReadPort(i);
			SB.WritePort("Reply: " + Msg);
		}
		SB.ClosePort();
	}
}