//服务端:发送信息
            
            try
            {
                string name_Message = nameComboBox.Text;//获取服务端消息文本
                int name_length = name_Message.Length;//定义整形变量length表示字符串Ser_message长度
                byte[] name_Send = new byte[name_length];//定义数组ser_Send,其长度为length
                name_Send = Encoding.UTF8.GetBytes(name_Message);
                //将消息转换为字节流存储在数组name_Send
                
                ser_Socket.Send(name_Send);//通过服务端socket发送信息                string sex_Message = sexComboBox.Text;
                int sex_Length = sex_Message.Length;
                byte[] sex_Send = new byte[sex_Length];
                sex_Send = Encoding.UTF8.GetBytes(sex_Message);
                ser_Socket.Send(sex_Send);                string age_Message = ageComboBox.Text;
                int age_Length = age_Message.Length;
                byte[] age_Send = new byte[age_Length];
                age_Send = Encoding.UTF8.GetBytes(age_Message);
                ser_Socket.Send(age_Send);                string addr_Message = addressComboBox.Text;
                int addr_Length = age_Message.Length;
                byte[] addr_Send = new byte[age_Length];
                addr_Send = Encoding.UTF8.GetBytes(addr_Message);
                ser_Socket.Send(addr_Send);                listBox1.Items.Add("服务端 " + server_Time + ":" + name_Message +
                    " " + sex_Message + " " + age_Message + " " + addr_Message);
                //在本机显示发送信息                listBox1.SelectedIndex = listBox1.Items.Count - 1;
                //保持listbox中的消息记录始终指向最后一条消息
             }
说明:服务端的发送信息框是和Access数据库相连接的,nameComboBox等读取的是数据库中的信息。客户端接收信息                while (tcpCon)
                {
                    TextBox.CheckForIllegalCrossThreadCalls = false;
                    byte[] name_Mess = new byte[1024];//字节数组存储来自服务端的消息
                    int n0 = cli_socket.Receive(name_Mess, name_Mess.Length, 0);
                    //n:保存着接受到的字节流的相应信息保存到字节数组Ser_mess里,
                    //包括长度,索引位置等(第三个参数指定为0)                    string name_message = Encoding.UTF8.GetString(name_Mess, 0, n0);
                    //从字节数组中读取字节流并用UTF8(读中文不出现乱码)读取成字符形式,
                    //从索引0开始,读取长度为n;                    listBox1.ForeColor = Color.DarkRed;
                    //服务端发送信息时显示框字体颜色为DarkRed                    nameTextBox.Text = name_message.ToString();//在文本框中显示信息                    byte[] sex_Mess = new byte[1024];
                    int n2 = cli_socket.Receive(sex_Mess, sex_Mess.Length, 0);
                    string sex_Message = Encoding.UTF8.GetString(sex_Mess, 0, n2);
                    sexTextBox.Text = sex_Message.ToString();                    byte[] age_Mess = new byte[1024];
                    int n3 = cli_socket.Receive(age_Mess, age_Mess.Length, 0);
                    string age_Message = Encoding.UTF8.GetString(age_Mess, 0, n3);
                    ageTextBox.Text = age_Message.ToString();                    byte[] addr_Mess = new byte[1024];
                    int n4 = cli_socket.Receive(addr_Mess, addr_Mess.Length, 0);
                    string addr_Message = Encoding.UTF8.GetString(addr_Mess, 0, n4);
                    addressTextBox.Text = addr_Message.ToString();                    listBox1.Items.Add("服务端 " + Client_time + ":" + name_message +
                        " " + sex_Message + " " + age_Message + " " + addr_Message);
                    listBox1.SelectedIndex = listBox1.Items.Count - 1;
                    //保持listbox1中的消息始终指向最后一条消息记录
                }
在用C#做C/S时,客户端与服务端已经连接成功,也可以通过Socket进行发送信息,只不过,在发送信息时,客户端必须先给服务端发一条信息,不然服务端发的信息在客户端无法显示,而当客户端发一个信息后才可以显示。
例如,通信连接后,服务端向客户端发送“服务端”后,但在客户端不显示,而在客户端向服务端发送一条信息后,才显示“服务端”。
还有一个问题是:当发送2个文本框的信息时,客户端可以正确的接收并显示信息,但是,当发送3个或4个文本框信息时,就不正常了。在客户端,带一个文本框显示正确,第二个文本框显示的是服务端发的第2个和第个3文本框的信息。
第三个问题是:如何在客户端与服务端连接上之后,服务端就可以直接向客户端发送信息,而且正确显示出来。大家帮忙看看,怎么解决一下。在此先谢过大家了。

解决方案 »

  1.   

    你这代码太粗糙了。不忍看了。没有任何服务端和客户端连接的代码。你先改改发送接受的方式吧,你这写法找错都难。在Tcp中只要服务端和客户端连接建立,无所谓谁给谁发,都可以收到。
      

  2.   

    今天我把代码全贴上来,大家好好看一下
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Data.OleDb;
    using System.Data.SqlClient;
    using System.Diagnostics;
    using System.Drawing;
    using System.IO;
    using System.Linq;
    using System.Net;
    using System.Net.Sockets;
    using System.Text;
    using System.Threading;
    using System.Windows.Forms;namespace socket服务端
    {
        public partial class Form1 : Form
        {
            public static readonly OleDbConnection con = new OleDbConnection("Provider=Microsoft.Jet.oledb.4.0;Data Source=" +
                Application.StartupPath + @"\DataBase\通讯录.mdb");        private int port = 8000;//设置通信双方的默认端口号为8000
            private TcpListener listener;//服务端用于侦听指定端口号
             private Thread ser_Thread;//创建服务端线程,用以侦听端口号,接收信息
             private bool lis_Statu = true;//初始化侦听状态为true
            private Socket ser_Socket;//服务端socket实例
             private string server_Time = DateTime.Now.ToLongTimeString();
            //服务端接受来自客户端消息时的时间         public Form1()
            {
                InitializeComponent();
            }        //窗体加载的时候将本机的一些信息获取并加载显示
             private void Form1_Load(object sender, EventArgs e)
            {
                try
                {
                    //server_Port.Text = port.ToString();//显示服务端开放的端口号
                      string hostIP = Dns.GetHostName();//定义变量hostIP保存主机IP
                    IPHostEntry mys = Dns.GetHostEntry(hostIP);//将主机IP地址解析为IPHostEntry实例
                      Local_IP.Text = mys.AddressList[0].ToString();//显示主机IP地址                  con.Open();
                    string select_sql = "select * from 通讯录 order by 姓名";
                    OleDbCommand cmd = new OleDbCommand();
                    cmd.CommandText = select_sql;
                    cmd.Connection = con;
                    OleDbDataAdapter datadapter = new OleDbDataAdapter(select_sql, con);
                    DataTable datable = new DataTable();
                    datadapter.Fill(datable);                nameComboBox.DataSource = datable;
                    nameComboBox.DisplayMember = datable.Columns[0].ColumnName;
                    nameComboBox.ValueMember = datable.Columns[0].ColumnName;                sexComboBox.DataSource = datable;
                    sexComboBox.DisplayMember = datable.Columns[1].ColumnName;
                    sexComboBox.ValueMember = datable.Columns[1].ColumnName;                ageComboBox.DataSource = datable;
                    ageComboBox.DisplayMember = datable.Columns[2].ColumnName;
                    ageComboBox.ValueMember = datable.Columns[2].ColumnName;                addressComboBox.DataSource = datable;
                    addressComboBox.DisplayMember = datable.Columns[3].ColumnName;
                    addressComboBox.ValueMember = datable.Columns[3].ColumnName;            }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
                finally
                {
                    con.Close();
                }
            }        //服务端:监听及接收信息
             private void Listen_btn_Click(object sender, EventArgs e)
            {
                ser_Thread = new Thread(new ThreadStart(Listen));
                ser_Thread.Start();//服务端线程开启 
                 //nameTextBox.ReadOnly = false;//可以向服务端发送信息框写信息
                 listBox1.Items.Clear();//清空listbox中的信息
             }        public void Listen()
            {
                TextBox.CheckForIllegalCrossThreadCalls = false;
                ListBox.CheckForIllegalCrossThreadCalls = false;            try
                {
                    IPAddress ip = IPAddress.Any;
                    //提供一个 IP 地址,指示服务器应侦听所有网络接口上的客户端活动
                    
                      listener = new TcpListener(ip, port);//初始化TcpListener实例
                      listener.Start();//开启监听服务
                      server_lable.Text = "正处于监听状态,等待客户端连接……";
                    ser_Socket = listener.AcceptSocket();//建立连接请求                  //如果网络环境良好并且连接请求成功
                      server_lable.Text = "已经连接!";
                    Close_Lis_btn.Enabled = true;//关闭监听按键可用
                      server_send.Enabled = true;//服务端发送信息按键可用
                      Listen_btn.Enabled = false;//监听按键不可用                  while(lis_Statu)
                    {
                       byte[] ser_Receive = new byte[1024];
                       //指定一个字节类型的数组用于接受客户端发来的字节流                      int n = ser_Socket.Receive(ser_Receive,ser_Receive.Length,0);
                       //n:保存着接受到的字节流的相应信息保存到字节数组bt_Receive里,
                          //包括长度,索引位置等(第三个参数指定为0)                      string client_Mess = Encoding.UTF8.GetString(ser_Receive,0,n);
                       //从字节数组中读取字节流并用UTF8(读中文不出现乱码)读取成字符形式,
                          //从索引0开始,读取长度为n                   if (client_Mess.Trim() != "stop")//"stop"用于关闭服务端一些服务
                          {
                          listBox1.ForeColor = Color.Green;//颜色用于区别发送方对象
                             listBox1.Items.Add("客户端 " + server_Time + ":" + client_Mess);
                          listBox1.SelectedIndex = listBox1.Items.Count - 1;
                          //保持listbox1中的消息始终指向最后一条消息记录
                          }
                       else
                       {
                           server_lable.Text = "连接已终止!";
                           server_send.Enabled = false;//服务端发送信息按键不可用
                              Listen_btn.Enabled = true;//监听按键可用              
                              listener.Stop();//关闭侦听
                              ser_Socket.Close();//关闭套接字                   
                              ser_Thread.Abort();//终止服务端的监听进程
                          }          
                    }              
                }
                catch (System.Security.SecurityException)
                {
                    MessageBox.Show("侦听失败", "Error", 
                        MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        
            //服务端:关闭监听
             private void Close_Lis_btn_Click(object sender, EventArgs e)
            {
                try
                {   server_lable.Text = "监听已经停止!";
                    server_send.Enabled = false;//服务端发送信息按键不可用
                      Listen_btn.Enabled = true;//监听按键可用            
                      ser_Socket.Close();//服务端socket关闭
                      listener.Stop();//关闭监听
                      ser_Thread.Abort();//关闭服务端线程          
                  }
                catch (Exception)
                {
                    MessageBox.Show("你未进行任何通信,确认关闭未开启的服务端线程吗?");
                }
            }        
            private void server_send_Click(object sender, EventArgs e)
            {
                //服务端:发送信息
                
                  try
                {
                    string name_Message = nameComboBox.Text;//获取服务端消息文本
                      int name_length = name_Message.Length;//定义整形变量length表示字符串Ser_message长度
                      byte[] name_Send = new byte[name_length];//定义数组ser_Send,其长度为length
                    name_Send = Encoding.UTF8.GetBytes(name_Message);
                    //将消息转换为字节流存储在数组name_Send
                    
                    ser_Socket.Send(name_Send);//通过服务端socket发送信息                  string sex_Message = sexComboBox.Text;
                    int sex_Length = sex_Message.Length;
                    byte[] sex_Send = new byte[sex_Length];
                    sex_Send = Encoding.UTF8.GetBytes(sex_Message);
                    ser_Socket.Send(sex_Send);                string age_Message = ageComboBox.Text;
                    int age_Length = age_Message.Length;
                    byte[] age_Send = new byte[age_Length];
                    age_Send = Encoding.UTF8.GetBytes(age_Message);
                    ser_Socket.Send(age_Send);                string addr_Message = addressComboBox.Text;
                    int addr_Length = age_Message.Length;
                    byte[] addr_Send = new byte[age_Length];
                    addr_Send = Encoding.UTF8.GetBytes(addr_Message);
                    ser_Socket.Send(addr_Send);                listBox1.Items.Add("服务端 " + server_Time + ":" + name_Message +
                        " " + sex_Message + " " + age_Message + " " + addr_Message);
                    //在本机显示发送信息                   listBox1.SelectedIndex = listBox1.Items.Count - 1;
                    //保持listbox中的消息记录始终指向最后一条消息              }
                catch(Exception)
                {
                    MessageBox.Show("发送失败!");
                }          
            }        //整个程序退出
             private void exit_btn_Click(object sender, EventArgs e)
            {
                  ser_Socket.Close();   //关闭服务端socket
                ser_Thread.Abort();   //关闭服务端线程
                  Application.Exit();   //关闭应用程序
             }        private void getLocalIP_Click(object sender, EventArgs e)
            {
                string hostIP = Dns.GetHostName();//定义变量hostIP保存主机IP
                IPHostEntry mys = Dns.GetHostEntry(hostIP);//将主机IP地址解析为IPHostEntry实例
                  Local_IP.Text = mys.AddressList[0].ToString();//显示主机IP地址
             }
        }
    }
      

  3.   

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Diagnostics;
    using System.Drawing;
    using System.Linq;
    using System.Net;
    using System.Net.Sockets;
    using System.Text;
    using System.Threading;
    using System.Windows.Forms;
    using System.IO;namespace socket通信
    {
        public partial class Form1 : Form
        {        private int port = 8000;//设置通信双方的默认端口号为8000
            private Thread cli_thrRead;//创建客户端端线程
            private Socket cli_socket;//客户端socket实例
            private bool tcpCon = false;//初始化客户端tcp连接状态为"False",未连接
            string Client_time = DateTime.Now.ToLongTimeString();//获取客户端时间        public Form1()
            {
                InitializeComponent();
            }        //客户端:通过指定IP和端口号连接服务器
            private void conect_btn_Click(object sender, EventArgs e)
            {
                try
                {
                    cli_socket = new Socket(AddressFamily.InterNetwork,
                        SocketType.Stream, ProtocolType.Tcp);
                    //配置socket参数,分别是地址协议族,socket类型,协议类型                IPEndPoint ipEnd = new IPEndPoint(IPAddress.Parse(server_ip.Text.Trim()), port);
                    //表示一个特定的IP地址和端口的组合,由socket绑定到非本地或本地地址                 EndPoint epTemp = (EndPoint)ipEnd;//EndPoint是IPEndPoint的基类                //创建远程终结点
                    cli_socket.Connect(epTemp);//连接目的主机                //如果连接成功,进度条显示连接成功信息
                    client_lable.Text = "连接远程计算机成功!";
                  tcpCon = true;//设置tcpCon连接状态为"true",连接
                    conect_btn.Enabled = false;//连接按键不可用
                    disconnectt_btn.Enabled = true;//断开连接按键可用
                    client_send.Enabled = true;//客户端发送按键可用
                    listBox1.Items.Clear();//清空发送信息框信息
                  }
                catch (Exception)
                {
                    client_lable.Text = "连接服务端失败!请检查网络环境和配置";
                }
            }        //客户端:断开与服务器的连接
             private void disconnectt_btn_Click(object sender, EventArgs e)
            {
                try
                {
                    close_Socket("stop");//调用close_Socket()函数来关闭一些服务
                      client_lable.Text = "与服务端的连接终止!";
                    client_send.Enabled = false;//客户端发送按键不可用
                      conect_btn.Enabled = true;//连接按键可用
                      tcpCon = false;//设置tcpCon连接状态为"false",未连接
                      cli_socket.Close();//关闭客户端socket
                    cli_thrRead.Abort();//关闭客户端线程
                 }
                catch (Exception)
                {
                    MessageBox.Show("确定不向服务端发送任何消息就关闭套接字吗?");
                }
            }        //客户端:发送信息
             private void client_send_Click(object sender, EventArgs e)
            {
                try
                {
                    string name_Message = nameTextBox.Text;
                    //定义name_Message获取客户端发送信息框信息
                    
                      int length = name_Message.Length;//获取客户端消息字长
                      byte[] name_Info = new byte[length];
                    //创建一个长度为length的字节数组保存消息                  name_Info = Encoding.UTF8.GetBytes(name_Message);
                    //将消息转化为字节流存储在send_Info中                  cli_thrRead = new Thread(new ThreadStart(Receive));
                    //此进程负责不间断的从服务端接收消息直至进程结束!                  cli_thrRead.Start();//开启进程
                      cli_socket.Send(name_Info);//通过客户端socket发送信息                  if (name_Message.Trim() != "stop")//如果发送信息不是“stop”
                      {
                        listBox1.Items.Add("客户端 " + Client_time + ":" + name_Message);
                    }
                    else
                    {
                        close_Socket("stop");
                        client_lable.Text = "已经关闭与远程计算机的连接。";
                        client_send.Enabled = false;//客户端发送按键不可用
                           conect_btn.Enabled = true;//连接按键可用
                           tcpCon = false;//设置tcpCon连接状态为"false",未连接
                           cli_socket.Close();//关闭客户端socket
                        cli_thrRead.Abort();//关闭客户端线程  
                      }
                }            catch (Exception)
                {
                    MessageBox.Show("服务端的监听服务可能已经关闭!");
                }
                finally
                {
                    listBox1.SelectedIndex = listBox1.Items.Count - 1;
                    //保持listbox中的消息始终指向最后一条消息记录
                }
           }        private void close_Socket(string strCmd)//关闭客户端的相应服务
            {
                if (tcpCon)
                {
                    try
                    {   
                        //将"stop"发送给服务端!!!,告诉服务端通话该结束了!!!                    client_send.Enabled = true;//客户端发送按键可用
                        byte[] stop_Mess = new byte[strCmd.Length];
                        //定义数组stop_Mess,长度未定                    stop_Mess = Encoding.UTF8.GetBytes(strCmd);
                        //将信息转换为字节流存储在stop_Mess数组中                    cli_socket.Send(stop_Mess);
                        //通过客户端socket发送stop_Mess数组信息                    tcpCon = false;//连接状态为False,未连接
                        cli_socket.Close();//关闭客户端socket
                        cli_thrRead.Abort();//关闭客户端线程
                      
                        if (strCmd == "stop")
                        {
                            tcpCon = false;//tcp连接断开
                            client_send.Enabled = false;//客户端发送信息按键不可用
                        }
                    }
                    catch (Exception)
                    {
                        MessageBox.Show("连接断开!");
                    }
                }
            }        protected void Receive()
            { 
                  try
                {
                    while (tcpCon)
                    {
                        TextBox.CheckForIllegalCrossThreadCalls = false;
                        byte[] name_Mess = new byte[1024];//字节数组存储来自服务端的消息
                           int n0 = cli_socket.Receive(name_Mess, name_Mess.Length, 0);
                        //n:保存着接受到的字节流的相应信息保存到字节数组Ser_mess里,
                           //包括长度,索引位置等(第三个参数指定为0)                       string name_message = Encoding.UTF8.GetString(name_Mess, 0, n0);
                        //从字节数组中读取字节流并用UTF8(读中文不出现乱码)读取成字符形式,
                           //从索引0开始,读取长度为n;                       listBox1.ForeColor = Color.DarkRed;
                        //服务端发送信息时显示框字体颜色为DarkRed                    nameTextBox.Text = name_message.ToString();//在文本框中显示信息                       byte[] sex_Mess = new byte[1024];
                        int n2 = cli_socket.Receive(sex_Mess, sex_Mess.Length, 0);
                        string sex_Message = Encoding.UTF8.GetString(sex_Mess, 0, n2);
                        sexTextBox.Text = sex_Message.ToString();                    byte[] age_Mess = new byte[1024];
                        int n3 = cli_socket.Receive(age_Mess, age_Mess.Length, 0);
                        string age_Message = Encoding.UTF8.GetString(age_Mess, 0, n3);
                        ageTextBox.Text = age_Message.ToString();                    byte[] addr_Mess = new byte[1024];
                        int n4 = cli_socket.Receive(addr_Mess, addr_Mess.Length, 0);
                        string addr_Message = Encoding.UTF8.GetString(addr_Mess, 0, n4);
                        addressTextBox.Text = addr_Message.ToString();                    listBox1.Items.Add("服务端 " + Client_time + ":" + name_message +
                            " " + sex_Message + " " + age_Message + " " + addr_Message);
                        listBox1.SelectedIndex = listBox1.Items.Count - 1;
                        //保持listbox1中的消息始终指向最后一条消息记录
                      }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }        //整个程序退出
             private void exit_btn_Click(object sender, EventArgs e)
            {
                close_Socket("stop");
                //为了不发生异常,这里先调用close_Socket()函数关闭一些服务          
                cli_socket.Close();//关闭客户端socket
                cli_thrRead.Abort();//关闭客户端线程
                  Application.Exit();//关闭应用程序
             }
        }
    }
      

  4.   


    byte[] sex_Mess = new byte[1024];
    byte[] age_Mess = new byte[1024];
    byte[] addr_Mess = new byte[1024];这是为了接收服务端发送过来的信息,而设置的接收数组的长度,有问题么?
    本来想用循环,可是,这个文本框的名字不好统一,所以就单独定义对应的接收数组来存放了。
    还有,发送那边也一样,单独发送了。
    “一个用户只允许连续回复3次。”
    不好意思,我应该先回复你的。
      

  5.   

    在发送端,
    string name_Message = nameComboBox.Text;//获取服务端消息文本
      int name_length = name_Message.Length;//定义整形变量length表示字符串Ser_message长度
      byte[] name_Send = new byte[name_length];//定义数组ser_Send,其长度为length
      name_Send = Encoding.UTF8.GetBytes(name_Message);
      //将消息转换为字节流存储在数组name_Send
        
      ser_Socket.Send(name_Send);//通过服务端socket发送信息这个发送没问题。在接收端
    byte[] name_Mess = new byte[1024];//字节数组存储来自服务端的消息
      int n0 = cli_socket.Receive(name_Mess, name_Mess.Length, 0);
      //n:保存着接受到的字节流的相应信息保存到字节数组Ser_mess里,
      //包括长度,索引位置等(第三个参数指定为0)  string name_message = Encoding.UTF8.GetString(name_Mess, 0, n0);
      //从字节数组中读取字节流并用UTF8(读中文不出现乱码)读取成字符形式,
      //从索引0开始,读取长度为n;  listBox1.ForeColor = Color.DarkRed;
      //服务端发送信息时显示框字体颜色为DarkRed  nameTextBox.Text = name_message.ToString();//在文本框中显示信息也没有问题,为了多发送几个文本框信息,多定义了几个,进行发送和接收,当发送2个时,没问题,三个以上时就不对了,接收端把第2个和第3个文本框的信息接收到后放到了同一个文本框中显示,为什么在接收端分明有各自相应的数组和文本框等,他们不分开显示呢。
    就是不明白为什么。