iT邦幫忙

DAY 7
8

VC# 網路(遊戲)程式設計 由淺入深系列 第 8

VC# 網路(遊戲)程式設計 由淺入深(5)-伺服端Socket程式流程說明與實作(2 Server端實作)

全系列:< http://ithelp.ithome.com.tw/event/ironmanarticle3/id/20033582>
上一篇:< http://ithelp.ithome.com.tw/question/10052889>
下一篇:http://ithelp.ithome.com.tw/question/10053166
如果你覺得本文不錯,麻煩推個文~~

經過前兩天1-1和1-2,相信各位應該比較了解伺服端Sokcet程式的流程以及System.Net.Sockets的使用方式了吧.
而本篇將實作伺服端Socket程式.
首先請開啟一個Windows Form專案,之後在裡面加入一個C#類別,命名為ListenClient:

之後表單配置為如下圖:

Form程式碼:

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

namespace ServerSocket
{
 public partial class Form1 : Form
 {
 Socket serverSocket = null;
   public Form1()
    {
      InitializeComponent();
    }
 private void Button1_Click(object sender, EventArgs e)
 {
   try
 {
 serverSocket = new Socket(AddressFamily.InterNetwork,
 SocketType.Stream, ProtocolType.Tcp);
string hostname = Dns.GetHostName();
IPAddress serverIP = Dns.Resolve(hostname).AddressList[0];
 
   string Port = "80";
IPEndPoint serverhost = new IPEndPoint(serverIP, Int32.Parse(Port));
serverSocket.Bind(serverhost);
serverSocket.Listen(50);
ListBox1.Items.Clear();
ListBox1.Items.Add("伺服器開始運作了: " + serverIP.ToString() + ":" + Port);
ListenClient lc = new ListenClient(serverSocket, this);

ThreadStart serverThreadStart = new ThreadStart(lc.ServerThreadProc);
Thread serverthread = new Thread(serverThreadStart);
serverthread.Start();
}
catch (Exception ex)
{
ListBox1.Items.Add(ex.StackTrace.ToString());
}
finally
{
}
}
}
}

ListenClient的程式碼:

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

namespace ServerSocket
{
  class ListenClient
  {
private System.Net.Sockets.Socket serverSocket;
private System.Net.Sockets.Socket clientSocket;

private Form1 MainForm;

public ListenClient(Socket serverSocket, Form1 MainForm)
{
this.serverSocket = serverSocket;
this.MainForm = MainForm;
}
public void ServerThreadProc()
{
 while (true)
{
try
{
clientSocket = serverSocket.Accept();
IPEndPoint serverInfo = (IPEndPoint)serverSocket.LocalEndPoint;
IPEndPoint clientInfo = (IPEndPoint)clientSocket.RemoteEndPoint;
MainForm.ListBox1.Items.Add("Server: " + serverInfo.Address.ToString() + ":" + serverInfo.Port.ToString());
MainForm.ListBox1.Items.Add("Client: " + clientInfo.Address.ToString() + ":" + clientInfo.Port.ToString());
}
catch (Exception ex)
{
Console.WriteLine(ex.StackTrace.ToString());
}
}
}
}
}

整個程式的運作幾乎都是在ListenClient類別裡面,
利用Form只是為了帶入圖形化介面,以及將一些設定傳出

˙ListneClient類別程式碼解析:

public ListenClient(Socket serverSocket, Form1 MainForm)
{
this.serverSocket = serverSocket;
this.MainForm = MainForm;
}
  • 這是建構函式,前面幾篇有看的讀者應該馬上就知道了.

    clientSocket = serverSocket.Accept();

  • 接受及處理用戶端的連線.

    IPEndPoint serverInfo = (IPEndPoint)serverSocket.LocalEndPoint;

  • 取得與本機相關的連線資訊

    IPEndPoint clientInfo = (IPEndPoint)clientSocket.RemoteEndPoint;

  • 取得用戶端相關的網路連線資訊

    MainForm.ListBox1.Items.Add("Server: " + serverInfo.Address.ToString() + ":" + serverInfo.Port.ToString());
    MainForm.ListBox1.Items.Add("Client: " + clientInfo.Address.ToString() + ":" + clientInfo.Port.ToString());

  • 將得到的本機及客戶端相關的連線資料加入到ListBox中(記錄)

˙Form程式碼解析

 string Port = "80";
  • 連線埠設定為80

    serverSocket.Bind(serverhost);

  • 設定伺服端用的IP

    serverSocket.Listen(50);

  • 設定伺服器的最大連線量

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

    namespace ServerSocket
    {
    class ListenClient
    {
    private System.Net.Sockets.Socket serverSocket;
    private System.Net.Sockets.Socket clientSocket;

    private Form1 MainForm;

    public ListenClient(Socket serverSocket, Form1 MainForm)
    {
    this.serverSocket = serverSocket;
    this.MainForm = MainForm;
    }
    public void ServerThreadProc()
    {
    while (true)
    {
    try
    {
    clientSocket = serverSocket.Accept();
    IPEndPoint serverInfo = (IPEndPoint)serverSocket.LocalEndPoint;
    IPEndPoint clientInfo = (IPEndPoint)clientSocket.RemoteEndPoint;
    MainForm.ListBox1.Items.Add("Server: " + serverInfo.Address.ToString() + ":" + serverInfo.Port.ToString());
    MainForm.ListBox1.Items.Add("Client: " + clientInfo.Address.ToString() + ":" + clientInfo.Port.ToString());
    }
    catch (Exception ex)
    {
    Console.WriteLine(ex.StackTrace.ToString());
    }
    }
    }
    }
    }

0

  • 設置執行緒
    --
    ˙執行結果

練習題(簡答題放馬過來換了):

  1. 若想要限制伺服器的最大連線量,該怎麼做?
  2. 要取得本機端的連線資訊,該怎麼做?

全系列:http://ithelp.ithome.com.tw/event/ironmanarticle3/id/20033582
上一篇:http://ithelp.ithome.com.tw/question/10052889
下一篇:http://ithelp.ithome.com.tw/question/10053166
如果你覺得本文不錯,麻煩推個文~~


上一篇
VC# 網路(遊戲)程式設計 由淺入深(5)- 伺服端Socket程式流程說明與實作(1-2Sockets命名空間說明)
下一篇
VC# 網路(遊戲)程式設計 由淺入深(10)-Secure Socket Layer-Security命名空間應用方法
系列文
VC# 網路(遊戲)程式設計 由淺入深15

2 則留言

0
SunAllen
iT邦研究生 1 級 ‧ 2010-10-09 20:03:57

到現在...我的觀念還停留在GW-BasicOrz

GW-Basic..
你不會還精通Cobol吧囧

0
kradark
iT邦好手 1 級 ‧ 2010-10-10 01:39:41

不才老人我用VC++或BSD Socket, 使用single process/multiple select,
在下後面的分享會有!!!

我要留言

立即登入留言