计算机网络_课程实验实验报告

《计算机网络》课程实验

            Socket编程

                  

作者:              

专业: 信息管理与信息系统

班级:     

学号:  

成绩:                 

指导教师:       

                             

西南大学信息管理系

 

一、实验目的

  通过socket程序的编写、调试,掌握socket编程的基本方法,了解客户端与服务器端的特点。

二、实验内容

①学习socket编程使用的类和接口,着重掌握基于TCP、UDP协议的socket。

②编写服务器端的应用程序

③编写客户端的应用程序

④实现服务器端与客户端的交互

三、实验代码

using System.Net.Sockets;

using System.IO;

namespace SyncChatServer

{

    class User

    {

        public TcpClient client{get; private set;}

        public BinaryReader br{get; private set;}

        public BinaryWriter bw{get; private set;}

        public string userName {get; set; }

        public User(TcpClient client)

        {

            this.client = client;

            NetworkStream networkStream = client.GetStream();

            br = new BinaryReader(networkStream);

            bw = new BinaryWriter(networkStream);

        }

        public void Close()

        {

            br.Close();

            bw.Close();

            client.Close();

        }

    }

}

using System;

using System.Collections.Generic;

using System.Windows.Forms;

using System.Net;

using System.Net.Sockets;

using System.Threading;

namespace SyncChatServer

{

    public partial class MainForm : Form

    {

        private List<User> userList = new List<User>();

        IPAddress localAddress;

        private const int port = 51888;

        private TcpListener myListener;

        bool isNormalExit = false;

        public MainForm()

        {

            InitializeComponent();

            listBoxStatus.HorizontalScrollbar = true;

            IPAddress[] addrIP = Dns.GetHostAddresses(Dns.GetHostName());

            localAddress = addrIP[0];

            buttonStop.Enabled = false;

        }

        private void buttonStart_Click(object sender, EventArgs e)

        {

            myListener = new TcpListener(localAddress, port);

            myListener.Start();

            AddItemToListBox(string.Format("开始在{0}:{1}监听客户连接", localAddress, port));

       

            Thread myThread = new Thread(ListenClientConnect);

            myThread.Start();

            buttonStart.Enabled = false;

            buttonStop.Enabled = true;

        }

        private void ReceiveData(object userState)

        {

            User user = (User)userState;

            TcpClient client = user.client;

            while (isNormalExit == false)

            {

                string receiveString = null;

                try

                {

                    receiveString = user.br.ReadString();

                }

                catch

                {

                    if (isNormalExit == false)

                    {

                        AddItemToListBox(string.Format("与[{0}]失去联系,已终止接收该用户信息", client.Client.RemoteEndPoint));

                        RemoveUser(user);

                    }

                    break;

                }

                AddItemToListBox(string.Format("来自[{0}]:{1}", user.client.Client.RemoteEndPoint, receiveString));

                string[] splitString = receiveString.Split(',');

                switch (splitString[0])

                {

                    case "Login":

                        user.userName = splitString[1];

                        SendToAllClient(user, receiveString);

                        break;

                    case "Logout":

                        SendToAllClient(user, receiveString);

                        RemoveUser(user);

                        return;

                    case "Talk":

                        string talkString = receiveString.Substring(splitString[0].Length + splitString[1].Length + 2);

                        AddItemToListBox(string.Format("{0}对{1}说:{2}",

                            user.userName, splitString[1], talkString));

                        SendToClient(user, "talk," + user.userName + "," + talkString);

                        foreach (User target in userList)

                        {

                            if (target.userName == splitString[1] && user.userName != splitString[1])

                            {

                                SendToClient(target, "talk," + user.userName + "," + talkString);

                                break;

                            }

                        }

                        break;

                    default:

                        AddItemToListBox("什么意思啊:" + receiveString);

                        break;

                }

            }

        }

      

        private void SendToClient(User user, string message)

        {

            try

            {

         

                user.bw.Write(message);

                user.bw.Flush();

                AddItemToListBox(string.Format("向[{0}]发送:{1}",

                    user.userName, message));

            }

            catch

            {

                AddItemToListBox(string.Format("向[{0}]发送信息失败",

                    user.userName));

            }

        }

 

        private void RemoveUser(User user)

        {

            userList.Remove(user);

            user.Close();

            AddItemToListBox(string.Format("当前连接用户数:{0}", userList.Count));

        }

        private delegate void AddItemToListBoxDelegate(string str);

      

        private void AddItemToListBox(string str)

        {

            if (listBoxStatus.InvokeRequired)

            {

                AddItemToListBoxDelegate d = AddItemToListBox;

                listBoxStatus.Invoke(d, str);

            }

            else

            {

                listBoxStatus.Items.Add(str);

                listBoxStatus.SelectedIndex = listBoxStatus.Items.Count - 1;

                listBoxStatus.ClearSelected();

            }

        }

    

        private void buttonStop_Click(object sender, EventArgs e)

        {

            AddItemToListBox("开始停止服务,并依次使用户退出!");

            isNormalExit = true;

            for (int i = userList.Count - 1; i >= 0; i--)

            {

                RemoveUser(userList[i]);

            }

       

            myListener.Stop();

            buttonStart.Enabled = true;

            buttonStop.Enabled = false;

        }

      

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)

        {

            if (myListener != null)

            {

                buttonStop.PerformClick();

            }

        }

    }

}

using System;

using System.Windows.Forms;

using System.Net;

using System.Net.Sockets;

using System.Threading;

using System.IO;

namespace SyncChatClient

{

    public partial class MainForm : Form

    {

        private bool isExit = false;

        private TcpClient client;

        private BinaryReader br;

        private BinaryWriter bw;

        public MainForm()

        {

            InitializeComponent();

            Random r = new Random((int)DateTime.Now.Ticks);

            textBoxUserName.Text = "user" + r.Next(100, 999);

            listBoxOnlineStatus.HorizontalScrollbar = true;

        }

        /// <summary>

       

        /// </summary>

        private void buttonConnect_Click(object sender, EventArgs e)

        {

            buttonConnect.Enabled = false;

            try

            {

             

                client = new TcpClient(Dns.GetHostName(), 51888);

                AddTalkMessage("连接成功");

            }

            catch

            {

                AddTalkMessage("连接失败");

                buttonConnect.Enabled = true;

                return;

            }

           

            NetworkStream networkStream = client.GetStream();

     

            br = new BinaryReader(networkStream);

            bw = new BinaryWriter(networkStream);

            SendMessage("Login," + textBoxUserName.Text);

            Thread threadReceive = new Thread(new ThreadStart(ReceiveData));

            threadReceive.IsBackground = true;

            threadReceive.Start();

        }

        private void SendMessage(string message)

        {

            try

            {

              

                bw.Write(message);

                bw.Flush();

            }

            catch

            {

                AddTalkMessage("发送失败!");

            }

        }

        private void AddTalkMessage(string message)

        {

            if (richTextBoxTalkInfo.InvokeRequired)

            {

                MessageDelegate d = new MessageDelegate(AddTalkMessage);

                richTextBoxTalkInfo.Invoke(d, new object[] { message });

            }

            else

            {

                richTextBoxTalkInfo.AppendText(message + Environment.NewLine);

                richTextBoxTalkInfo.ScrollToCaret();

            }

        }

        private delegate void AddOnlineDelegate(string message);

     

        private void AddOnline(string userName)

        {

            if (listBoxOnlineStatus.InvokeRequired)

            {

                AddOnlineDelegate d = new AddOnlineDelegate(AddOnline);

                listBoxOnlineStatus.Invoke(d, new object[] { userName });

            }

            else

            {

                listBoxOnlineStatus.Items.Add(userName);

                listBoxOnlineStatus.SelectedIndex = listBoxOnlineStatus.Items.Count - 1;

                listBoxOnlineStatus.ClearSelected();

            }

        }

        private delegate void RemoveUserNameDelegate(string userName);

        private void RemoveUserName(string userName)

        {

            if (listBoxOnlineStatus.InvokeRequired)

            {

                RemoveUserNameDelegate d = RemoveUserName;

                listBoxOnlineStatus.Invoke(d, userName);

            }

            else

            {

                listBoxOnlineStatus.Items.Remove(userName);

                listBoxOnlineStatus.SelectedIndex = listBoxOnlineStatus.Items.Count - 1;

                listBoxOnlineStatus.ClearSelected();

            }

        }

        private void groupBox1_Enter(object sender, EventArgs e)

        {

        }

    }

}

四、程序运行过程

①运行服务器端程序。运行结果如下图。

②运行客户端程序,当客户端程序运行后,服务器端立即显示连接成功并等待客户端发送信息,结果如下图.

                       

                   服务器程序的运行结果

客户端运行结果

五、实验心得

1、巩固了以前基础的C#知识。

3、了解Socket类的作用与用法,会用一些Socket类的重要方法。

4、初步了解C#中用来实现客户端TCP操作Socket类,这个类本身使用直接代码通过主机操作系统的本地TCP栈进行通信。

六、参考书籍

1、《Windows Sockets网络编程》 奎因(Bob Quinn)、舒特(Dave Shute)、徐磊、 滕婧 机械工业出版社

2、《21世纪高等学校计算机规划教材:网络编程实用教程》 叶树华 人民邮电出版社

3、《Visual C#网络编程》郑阿奇 电子工业出版社

相关推荐