Программа для сокетов C # - PullRequest
0 голосов
/ 18 января 2012

Здравствуйте, я делаю программу для сокетов на C #, и теперь у меня возникла проблема.Я использую этот программный код сервера и этот код клиента, который я нашел.Я немного изменил его.Итак, проблема, с которой я столкнулся, заключается в том, что я хочу иметь возможность отключиться от сервера, я много пробовал и гуглил, но не могу понять, как это сделать.Какой простой способ сделать это с этим кодом ??

код клиента

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;

namespace soket_client_delen
{

public partial class Form1 : Form
{
    System.Net.Sockets.TcpClient clientSocket = new System.Net.Sockets.TcpClient();

    public Form1()
    {
        InitializeComponent();
        this.textBox2.KeyPress += new System.Windows.Forms.KeyPressEventHandler(CheckKeys);
    }
    private void CheckKeys(object sender, System.Windows.Forms.KeyPressEventArgs e)
    {
        if (e.KeyChar == (char)13)
        {
            // Then Enter key was pressed
            if (checkBox1.Checked ==true)
                send();
        }
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        msg("Client Started");
        clientSocket.Connect("127.0.0.1", 8888);

        label1.Text = "Client Socket Program - Server Connected ...";
    }


    private void button1_Click_1(object sender, EventArgs e)
    {
        send();
    }

    public void send()
    {
        NetworkStream serverStream = clientSocket.GetStream();
        byte[] outStream = System.Text.Encoding.ASCII.GetBytes(textBox2.Text +"$");
        textBox2.Text = "";
        serverStream.Write(outStream, 0, outStream.Length);
        serverStream.Flush();

        byte[] inStream = new byte[10025];
        serverStream.Read(inStream, 0, (int)clientSocket.ReceiveBufferSize);
        string returndata = System.Text.Encoding.ASCII.GetString(inStream);
        msg("Data from Server : " + returndata);
    }


    public void msg(string mesg)
    {
        textBox1.Text = textBox1.Text + Environment.NewLine + " >> " + mesg;
    }

    private void button2_Click(object sender, EventArgs e)
    {

    }

}
}

и код сервера:

using System;
using System.Net.Sockets;
using System.Text;
using System.Threading;

namespace soket_serverdelen
{
class Program
{
    static void Main(string[] args)
    {
        TcpListener serverSocket = new TcpListener(8888);
        TcpClient clientSocket = default(TcpClient);
        int counter = 0;

        serverSocket.Start();
        Console.WriteLine(" >> " + "Server Started");

        counter = 0;
        while (true)
        {
            counter += 1;
            clientSocket = serverSocket.AcceptTcpClient();
            Console.WriteLine(" >> " + "Client No:" + Convert.ToString(counter) + " started!");
            handleClinet client = new handleClinet();
            client.startClient(clientSocket, Convert.ToString(counter));
        }

        clientSocket.Close();
        serverSocket.Stop();
        Console.WriteLine(" >> " + "exit");
        Console.ReadLine();
    }
}

//Class to handle each client request separatly
public class handleClinet
{
    TcpClient clientSocket;
    string clNo;
    public void startClient(TcpClient inClientSocket, string clineNo)
    {
        this.clientSocket = inClientSocket;
        this.clNo = clineNo;
        Thread ctThread = new Thread(doChat);
        ctThread.Start();
    }
    private void doChat()
    {
        int requestCount = 0;
        byte[] bytesFrom = new byte[10025];
        string dataFromClient = null;
        Byte[] sendBytes = null;
        string serverResponse = null;
        string rCount = null;
        requestCount = 0;

        while ((true))
        {
            try
            {
                requestCount = requestCount + 1;
                NetworkStream networkStream = clientSocket.GetStream();
                networkStream.Read(bytesFrom, 0, (int)clientSocket.ReceiveBufferSize);
                dataFromClient = System.Text.Encoding.ASCII.GetString(bytesFrom);
                dataFromClient = dataFromClient.Substring(0, dataFromClient.IndexOf("$"));

                    rCount = Convert.ToString(requestCount);
                    serverResponse = "Server to clinet(" + clNo + ") " + rCount;
                    sendBytes = Encoding.ASCII.GetBytes(serverResponse);
                    networkStream.Write(sendBytes, 0, sendBytes.Length);
                    networkStream.Flush();
                    Console.WriteLine(" >> " + serverResponse);
            }
            catch (Exception ex)
            {
                Console.WriteLine(" >> " + ex.ToString());
            }
        }
    }
}
}

Спасибо вам за помощь

Ответы [ 3 ]

2 голосов
/ 18 января 2012
0 голосов
/ 18 января 2012

Вам нужно, чтобы обе стороны коллировали. Как правило, хотя это и не жесткое и быстрое правило, клиент прерывает соединение, и сторона сервера отвечает на это. Итак, когда ваш клиент завершил передачу / прием, клиентская сторона звонит близко. Затем серверная сторона отвечает на это и вызывает close на своей стороне.

Для клиентской стороны:

NetworkStream ns = clientSocket.GetStream();
// send important stuff
// receive important stuff from server
ns.Close();

Для серверной части:

NetworkStream ns = clientSocket.GetStream();
int bytesRead;
while((bytesRead = ns.Read(buffer, 0, buffer.Length)) >= 0) {
    if(bytesRead > 0) {
        // do really important stuff
    } else if(bytesRead == 0) {
        // client has trasmitted FIN packet, close and exit thread
        ns.Close();
    } else {
        // handle error condition
        // probably close the connection
    }
}

Приведенный выше код является только моделью. Я не проверял это. Вы используете сетевые потоки, поэтому этот пример (я думаю) должен быть полезным. Для этого я обычно использую select () (в Windows API .NET выставляет его в классе Socket). Обычно, когда любая из сторон закрывает соединение, с помощью Close () стеки TCP Windows отправляют пакет TCP FIN. Это сигнализирует о том, что отправляющая сторона желает закрыть соединение. Кроме того, кто-то заметил, что вы должны включить использование этих потоков в предложение using. Крайне важно, если вы не собираетесь вызывать Close () напрямую.

0 голосов
/ 18 января 2012

Обычно клиент отправляет на сервер сигнал о выходе из системы. При получении этого сообщения сервер закрывает соединение. Клиент должен выполнить цикл до serverStream.Socket.Closed = True перед выходом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...