OK、私のServer
フォームには、 TcpListenerを実行するBackgroundWorkerがあります。この TcpListener を BackgroundWorker に配置する必要があります。そうしないと、TcpClient を受け入れるまで実行を停止できません。
また、クロススレッド例外を防ぐために、このバックグラウンド スレッドから受け取ったすべてのデータを実行のメイン スレッドで処理する必要があります。
private TcpListener _listener;
private const int port = 8000;
private void Worker_TcpListener(object sender, DoWorkEventArgs e) {
BackgroundWorker worker = sender as BackgroundWorker;
do {
try {
_listener = new TcpListener(IPAddress.Any, port);
_listener.Start();
TcpClient client = _listener.AcceptTcpClient(); // waits until data is avaiable
int MAX = client.ReceiveBufferSize;
NetworkStream stream = client.GetStream();
Byte[] buffer = new Byte[MAX];
int len = stream.Read(buffer, 0, MAX);
if (0 < len) {
string data = Encoding.UTF8.GetString(buffer);
worker.ReportProgress(len, data.Substring(0, len));
}
stream.Close();
client.Close();
} catch (SocketException) {
// See MSDN: Windows Sockets V2 API Error Code Doc for details of error code
} catch (ThreadAbortException) { // If I have to call Abort on this thread
return;
} finally {
_listener.Stop();
}
} while (!worker.CancellationPending);
}
これは大きなメッセージ (JPEG ファイルなど) には向いていませんが、検索する特別なデータをコード化した短い文字列には適しています。
このデータは、(メソッドを使用して) 実行のメイン スレッドに送り返され、ReportProcess
そこでデータが処理されます。
private void Worker_TcpListener(object sender, ProgressChangedEventArgs e) {
if (e.UserState != null) {
int len = e.ProgressPercentage;
string data = e.UserState.ToString();
if (!String.IsNullOrEmpty(data) && (3 < len)) {
string head = data.Substring(0, 3);
string item = data.Substring(3);
if (!String.IsNullOrEmpty(item)) {
if (head == "BP:") {
string[] split = data.Split(';');
if (2 < split.Length) {
string box = split[0].Substring(3); // Box Number
string qty = split[1].Substring(2); // Quantity
string customer = split[2].Substring(2); // Customer Name
MyRoutine(box, qty, customer);
}
}
}
}
}
}
上記のコードは、一日中座って実行されます。
一方、工場には約 10 台の Pocket PC デバイスがあり、いつでもデータを送信できます。それらのコードは VB で書かれており、いつか C# バージョンを完成させたいと思っていますが、それは次のとおりです。
Private Sub SendToServer(string serialNum, int qty, string customer)
Cursor.Current = Cursors.WaitCursor
Try
Dim strPacket As String = String.Format("BP:{0};Q:{1};C:{2};", serialNum, qty, customer)
Dim colon As Integer = p7_txtIPAddress.Text.IndexOf(":")
Dim host As String = p7_txtIPAddress.Text.Substring(0, colon)
Dim port As Integer = CInt(p7_txtIPAddress.Text.Substring(colon + 1))
Dim dataPacket As [Byte]() = Encoding.ASCII.GetBytes(strPacket)
Using client As New TcpClient(host, port)
Dim stream As NetworkStream = client.GetStream()
stream.Write(dataPacket, 0, dataPacket.Length)
End Using
Catch err As Exception
MessageBox.Show(err.Message, "Print To Server TCP Error")
Finally
Cursor.Current = Cursors.Default
End Try
End Function
それがあなたがやろうとしていることかどうかはわかりませんが、機能し、信頼性があります。
明らかに、私が本番環境に持っているコードはより大きく、役に立たない他のもの (つまり、従業員の検証、エラー ロガーなど) が含まれています。私はそれらの多くを切り取ってきましたが、必要なものを何も切り取らなかったことを願っています.
これにより、少なくとも前進する方法についてのアイデアが得られるはずです。