有tcp异步通信代码,是服务端和客户端分开的,想把服务端和客户端合在一起,但有很多疑问:
1.如果A、B二台机器通信,A、B都启动了服务端,这时候B向A发出连接请求,双方建立一个socket套接字.问题是这时如果A又向B发出连接请求,难道又要建立一个socket套接字?直接用第一个socket可以吗?如果可以,在许多机器通信的情况下,又如何判断A、B已经建立连接,不用重新建立?
下面把下载的代码贴出来,帮我提下修改意见,谢谢!server:using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace qq
{
    public partial class Form1 : Form
    {
 
        public class StateObject
        {            public Socket workSocket = null;       // Client  socket.
            public const int BufferSize = 1024;       // Size of receive buffer.
            public byte[] buffer = new byte[BufferSize]; // Receive buffer.
            public StringBuilder sb = new StringBuilder();  // Received data string.            public StateObject()
            {
                // TODO: 在此处添加构造函数逻辑
            }
        }        private IPAddress myIP = IPAddress.Parse("127.0.0.1");
        private IPEndPoint MyServer;
        private Socket sock;
        private Socket handler;
        private static ManualResetEvent Done = new ManualResetEvent(false);  //通知正在等待待的线程已发生了事件        public Form1()
        {
            InitializeComponent();
        }
        private void Form1_Load(object sender, EventArgs e)
        {        }        private void button1_Click(object sender, EventArgs e)
        {            try
            {
                myIP = IPAddress.Parse(textBox1.Text);            }
            catch { MessageBox.Show("您输入的IP地址格式不正确,请重新输入!"); }
            try
            {
                MyServer = new IPEndPoint(myIP, Int32.Parse(textBox2.Text));
                sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                sock.Bind(MyServer);
                sock.Listen(50);
                
                toolStripStatusLabel1.Text = "主机" + textBox1.Text + "端口" + textBox2.Text + "开始监听......";
                Thread thread = new Thread(new ThreadStart(targett));
                thread.Start();
            }
            catch (Exception ee)
            {
                toolStripStatusLabel1.Text = ee.Message;            }
        }        #region 服务端接受连接,异步方式,向客户端发送‘准备完毕’信号,从客户端接收信号
        private void targett()
        {
            while (true)
            {
                Done.Reset();//阻塞线程
                sock.BeginAccept(new AsyncCallback(AcceptCallback), sock);
                Done.WaitOne();//阻塞当前线程,直到等到一个System.Threading.WaitHandle
            }
        }        private void AcceptCallback(IAsyncResult ar)
        {            Done.Set();//允许其它线程继续
            Socket listener = (Socket)ar.AsyncState;
            handler = listener.EndAccept(ar);            StateObject state = new StateObject();
            state.workSocket = handler;
            toolStripStatusLabel1.Text = "与客户建立连接。";
            try
            {
                byte[] byteData = System.Text.Encoding.BigEndianUnicode.GetBytes("准备完毕,可以通话!" + "\n\r");                handler.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), handler);            }
            catch (Exception ee) { MessageBox.Show(ee.Message); }            Thread thread = new Thread(new ThreadStart(rec));
            thread.Start();        }        private void rec()
        {
            StateObject state = new StateObject();
            state.workSocket = handler;
            handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);        }        private void ReadCallback(IAsyncResult ar)
        {
            StateObject state = (StateObject)ar.AsyncState;
            Socket tt = state.workSocket;
            int bytesRead = handler.EndReceive(ar);            state.sb.Append(System.Text.Encoding.BigEndianUnicode.GetString(state.buffer, 0, bytesRead));
            string content = state.sb.ToString();
            state.sb.Remove(0, content.Length);
            richTextBox1.AppendText(content + "\r\n");
            tt.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);        }        #endregion        private void button2_Click(object sender, EventArgs e)
        {
            try
            {
                byte[] byteData = System.Text.Encoding.BigEndianUnicode.GetBytes("准备完毕,可以通话!" + "\n\r");
                byte[] byteData = System.Text.Encoding.BigEndianUnicode.GetBytes(textBox3.Text + ">>>" + richTextBox2.Text + "\r\n");
                handler.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), handler);
                richTextBox2.Clear();////////////////////////////////////////////////            }
            catch (Exception ee) { MessageBox.Show(ee.Message); }
        }        private void SendCallback(IAsyncResult ar)
        {
            try
            {
                handler = (Socket)ar.AsyncState;
                int bytesSent = handler.EndSend(ar);
             //   richTextBox2.Text = "go send";
            }
            catch (Exception ee)
            {
                MessageBox.Show(ee.Message);
            }
        }        private void button3_Click(object sender, EventArgs e)
        {
            try
            {
                sock.Close();
                toolStripStatusLabel1.Text = "主机" + textBox1.Text + "端口" + textBox2.Text + "监听停止!";
            }
            catch { MessageBox.Show("监听尚未开始,关闭无效!"); }
        }
    }
}

解决方案 »

  1.   


    client:using System;
    using System.Drawing;
    using System.Collections;
    using System.ComponentModel;
    using System.Windows.Forms;
    using System.Data;
    using System.Net;
    using System.Net.Sockets;
    using System.Threading;
    using System.Text;namespace qqclient
    {
        public partial class Form1 : Form
        {
            public class StateObject
            {
                public Socket workSocket = null;              // Client socket.
                public const int BufferSize = 256;            // Size of receive buffer.
                public byte[] buffer = new byte[BufferSize];  // Receive buffer.
                public StringBuilder sb = new StringBuilder();// Received data string.            public StateObject()
                {
                    // TODO: 在此处添加构造函数逻辑
                }
            }        private IPAddress myIP = IPAddress.Parse("127.0.0.1");//新加的
            private IPEndPoint MyServer;//新加的 
            private Socket sock;        private static ManualResetEvent connectDone = new ManualResetEvent(false);
            private static ManualResetEvent sendDone = new ManualResetEvent(false);        public Form1()
            {
                InitializeComponent();
            }        private void Form1_Load(object sender, EventArgs e)
            {        }        private void button1_Click(object sender, EventArgs e)
            {
                try
                {
                    myIP = IPAddress.Parse(textBox1.Text);            }
                catch { MessageBox.Show("您输入的IP地址格式不正确,请重新输入!"); }
                try
                {
                    MyServer = new IPEndPoint(myIP, Int32.Parse(textBox2.Text));
                    sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);                sock.BeginConnect(MyServer, new AsyncCallback(ConnectCallback), sock);
                    connectDone.WaitOne();
                }
                catch (Exception ee) { MessageBox.Show(ee.Message); }        }        private void ConnectCallback(IAsyncResult ar)
            {
                try
                {                Socket client = (Socket)ar.AsyncState;                client.EndConnect(ar);                try
                    {
                        byte[] byteData = System.Text.Encoding.BigEndianUnicode.GetBytes("准备完毕,可以通话!!" + "\n\r");
                        sock.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), sock);                }
                    catch (Exception ee) { MessageBox.Show(ee.Message); }
                    toolStripStatusLabel1.Text = "与主机" + textBox1.Text + "端口" + textBox2.Text + "建立连接!";                Thread thread = new Thread(new ThreadStart(targett));
                    thread.Start();                connectDone.Set();
                }
                catch
                {            }
            }        private void button2_Click(object sender, EventArgs e)
            {
                byte[] byteData = System.Text.Encoding.BigEndianUnicode.GetBytes(textBox3.Text + ">>>" + richTextBox2.Text + "\r\n");            sock.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), sock);
                richTextBox2.Clear();        }
            private void SendCallback(IAsyncResult ar)
            {
                try
                {                Socket client = (Socket)ar.AsyncState;
                    client.EndSend(ar);  //i add
                    sendDone.Set();
                }
                catch (Exception ee)
                {
                    MessageBox.Show(ee.Message);
                }
            }
            private void targett()
            {            try
                {
                    StateObject state = new StateObject();
                    state.workSocket = sock;                sock.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
                }
                catch (Exception ee)
                {
                    MessageBox.Show(ee.Message);
                }
            }        private void ReceiveCallback(IAsyncResult ar)
            {
                try
                {                StateObject state = (StateObject)ar.AsyncState;
                    Socket client = state.workSocket;
                    int bytesRead = client.EndReceive(ar);
                    client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
                    state.sb.Append(System.Text.Encoding.BigEndianUnicode.GetString(state.buffer, 0, bytesRead));
                    string aa = state.sb.ToString();
                    state.sb.Remove(0, aa.Length);
                    richTextBox1.AppendText(aa + "cccc"+"\r\n");            }
                catch
                {            }
            }
            private void button3_Click(object sender, EventArgs e)
            {
                try
                {
                    sock.Close();
                    toolStripStatusLabel1.Text = "与主机" + textBox1.Text + "端口" + textBox2.Text + "断开连接!";
                }
                catch { MessageBox.Show("连接尚未建立,断开无效!"); }        }
        }
    }
      

  2.   

    明显vc2003的代码.net2.0以上就跑不了啦。。
    你要实现相互通信那你客户端也要对服务端进行监听吧?
    你可以在客户端也开个线程
      

  3.   

    我刚才试验了以下,可以把上面说的方法否定掉了,我自己鄙视一下我自己
    方法是在你client代码的
    try 
                { 
                    MyServer = new IPEndPoint(myIP, Int32.Parse(textBox2.Text)); 
                    sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);                 sock.BeginConnect(MyServer, new AsyncCallback(ConnectCallback), sock); 
                    connectDone.WaitOne(); 
    这部分后面加采用异步的BeginReceive,
                        StateObject state = new StateObject();
                        state.workSocket = Sock;
                        Sock.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                              new AsyncCallback(ReadCallback), state);
    这个的实现和你服务端的差不多,用来接收服务端的socket,不需要使用thread在服务端我用同步的send试验了一下可以发出去在
    你server端的代码
     handler = listener.EndAccept(ar); 利用这个handler 或者state.workSocket
    你想怎么send就怎么send
      

  4.   

    按楼主的代码,如果是已经连接上的Socket,那么再次连接是不会响应的其实如果要防止重新连接可以在连接上服务器后Enable你的连接Button就可以了另外,关于socket的关闭楼主还要好好处理一下,关闭服务器端前要先向客户端发送一个关闭socket 的标识