【问题标题】:Winsock server/client application in c#c#中的Winsock服务器/客户端应用程序
【发布时间】:2016-05-14 11:38:15
【问题描述】:

我正在使用 winsock Control 在 C# 中制作客户端/服务器应用程序。我做了所有的事情,但我坚持将数据从客户端发送到服务器的地方。在我的程序中,服务器始终使用 ip 和端口监听客户端。我将数据从客户端发送到服务器。

1)当点击服务器窗体上的监听按钮时,它会打开客户端连接的服务器。

2)在第一个客户端表单中,我单击连接按钮以表明服务器已连接 为该消息提供一条消息(连接事件:ip),我们很容易知道客户端已连接到服务器。

3)然后我们在发送数据文本框中输入一些数据,然后单击发送按钮将数据发送到服务器并保存在客户端。

代码如下:

服务器:

using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Net;
using System.Threading;
using System.Net.Sockets;

namespace Server
{
    public partial class Form1 : Form
    {      
        public Form1()
        {
            InitializeComponent();        
        }
        const string DEFAULT_SERVER = "ip";
        const int DEFAULT_PORT = 120;

        System.Net.Sockets.Socket serverSocket;
        System.Net.Sockets.SocketInformation serverSocketInfo;

        public string Startup()
        {               
            IPHostEntry hostInfo = Dns.GetHostByName(DEFAULT_SERVER);
            IPAddress serverAddr = hostInfo.AddressList[0];
            var serverEndPoint = new IPEndPoint(serverAddr, DEFAULT_PORT);            
            serverSocket = new System.Net.Sockets.Socket(System.Net.Sockets.AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Stream, System.Net.Sockets.ProtocolType.Tcp);
            serverSocket.Bind(serverEndPoint);

            return serverSocket.LocalEndPoint.ToString();    
        }

        public string Listen()
        {
            int backlog = 0;
            try
            {
                serverSocket.Listen(backlog);
                return "Server listening";
            }
            catch (Exception ex)
            {
                return "Failed to listen" + ex.ToString();
            }
        }
        public string ReceiveData()
        {
            System.Net.Sockets.Socket receiveSocket;

            byte[] buffer = new byte[256];

            receiveSocket = serverSocket.Accept();

            var bytesrecd = receiveSocket.Receive(buffer);

            receiveSocket.Close();

            System.Text.Encoding encoding = System.Text.Encoding.UTF8;

            return encoding.GetString(buffer);
        }           

        private void Listen_Click(object sender, EventArgs e)
        {
            string serverInfo = Startup();
            textBox1.Text = "Server started at:" + serverInfo;

            serverInfo = Listen();
            textBox1.Text = serverInfo;

            //string datatosend = Console.ReadLine();
            //SendData(datatosend);

            serverInfo = ReceiveData();
            textBox1.Text = serverInfo;

            //Console.ReadLine();
        }

        private void winsock_DataArrival(object sender, AxMSWinsockLib.DMSWinsockControlEvents_DataArrivalEvent e)
        {
            ReceiveData();
            Listen();
        }

        private void winsock_ConnectEvent(object sender, EventArgs e)
        {
            Listen();
        }
    }
}

这一切都完美无缺,但我的问题是我只能一次从客户端获取数据到服务器。当我再次从客户端向服务器发送数据时,它不起作用并给了我一些类似的消息

附加信息:每个套接字地址只能使用一次 (协议/网络地址/端口)通常是允许的

在服务器表单中

serverSocket.Bind(serverEndPoint);

请有人帮我解决我的问题。

谢谢。

【问题讨论】:

  • 为什么调用receiveSocket.Close();在 ReceiveData() 中?这可能是问题所在。
  • @Mitesh Budhabhatti 感谢您的宝贵命令。我命令那一行 //receiveSocket.Close();但我又遇到了同样的问题;-(
  • @Sanjana - 您还需要显示客户端代码才能解决问题!
  • 我只在服务器中遇到了问题。 go4expert.com/articles/winsock-c-sharp-t3312 这是我的客户。
  • 我需要监听服务器不断监听端口。如果我一次又一次地从客户端发送数据,服务器会不断地获取数据

标签: c# client-server winsock


【解决方案1】:

试试这个。它可以帮助你

delegate void AddTextCallback(string text);

public Form1()
{
    InitializeComponent();
}
private void ButtonConnected_Click(object sender, EventArgs e)
{
    ThreadPool.QueueUserWorkItem(new WaitCallback(ServerHandler));
}

private void ServerHandler(object state)
{
    TcpListener _listner = new TcpListener(IPAddress.Parse("12.2.54.658"), 145);

    _listner.Start();

    AddText("Server started - Listening on port 145");

    Socket _sock = _listner.AcceptSocket();

    //AddText("User from IP " + _sock.RemoteEndPoint);

    while (_sock.Connected)
    {
        byte[] _Buffer = new byte[1024];

        int _DataReceived = _sock.Receive(_Buffer);

        if (_DataReceived == 0)
        {
            break;
        }

        AddText("Message Received...");

        string _Message = Encoding.ASCII.GetString(_Buffer);

        AddText(_Message);
    }

    _sock.Close();
    AddText("Client Disconnected.");

    _listner.Stop();
    AddText("Server Stop.");
}

private void AddText(string text)
{
    if (this.listBox1.InvokeRequired)
    {
        AddTextCallback d = new AddTextCallback(AddText);
        this.Invoke(d, new object[] { text });
    }
    else
    {
        this.listBox1.Items.Add(text);
    }
}

上个月我也遇到了和你一样的问题,但我使用 stackoverflow 中的 Receive multiple different messages TcpListener C# 解决了这个问题。这对我很有帮助,希望它也有助于解决您的问题。

【讨论】:

  • 感谢 Arthi,它对我很有帮助。它解决了我的问题
【解决方案2】:

我不是 100% 确定你了解 TCP 套接字,所以这里是。

当您使用 TCP 侦听器套接字时,您首先绑定到一个端口,以便客户端有一个固定的、已知的连接点。这会为您的套接字保留端口,直到您通过在该套接字上调用 Close() 放弃它。

接下来您侦听以开始在您绑定的端口上接受客户端的过程。您可以同时执行此操作和第一步,但您没有,我没有。

接下来你打电话给Accept()。这会阻塞(停止执行),直到客户端连接,然后它返回一个专用于与该客户端通信的套接字。如果你想允许另一个客户端连接,你必须再次调用Accept()

然后您可以使用Accept() 返回的套接字与您的客户端通信,直到完成,此时您在该套接字上调用Close()

当您侦听完新连接后,您可以在侦听器套接字上调用 Close()


但是,当您按下收听按钮时,会发生以下情况:

您正确绑定,您开始正确收听,然后您对 ReceiveData() 的调用会阻塞 Accept 调用,直到收到客户端。然后您会收到一些数据(尽管这是 TCP,因此可能不是全部数据!),然后您立即关闭与客户端的连接。

我想你会得到你得到的错误,然后你必须在你的服务器上再次按听。因此,这将重新启动整个侦听器套接字,并且当您第二次绑定到该端口时,您的前一个侦听器仍然绑定到它,因此调用失败,因为该端口上已经分配了一些东西。


明智的解决方案是,您需要保持从Accept() 调用返回的套接字打开,直到您完成它。让客户端通过在其套接字上调用Shutdown() 方法来处理关闭,或者建立一些约定来标记通信结束。

当您尝试连接多个用户时也会遇到麻烦,因此在某些时候您需要线程或一些异步套接字,但我觉得这超出了这个问题的范围。

【讨论】:

    【解决方案3】:

    我建议你不要使用 AxMSWinsockLib。看看这里给出的套接字示例,它展示了如何创建客户端套接字和服务器套接字 - https://msdn.microsoft.com/en-us/library/kb5kfec7(v=vs.110).aspx 和这个 - https://msdn.microsoft.com/en-us/library/6y0e13d3(v=vs.110).aspx

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多