生活随笔
收集整理的這篇文章主要介紹了
C#游戏客户端编程
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
目錄
一、TCP客戶端與服務器端通信
服務器初始化
(1)調用socket,創建文件描述符
(2)調用bind,將文件描述符與ip/port連接起來。若端口號已被占用,則bind失敗
(3)調用listen,聲明該文件描述符是服務器的一個文件描述符,為之后的accept做準備
(4)調用accept,并處于阻塞狀態,等待客戶端連接
建立連接
(1)調用socket,創建文件描述符
(2)調用connect,向服務器發起連接請求。
(3)connect會發送一個請求SYN段并阻塞等待服務器應答(第一次)
(4)服務器收到SYN,會給客戶端發送一個確認應答的同時發送一個請求(SYN+ACK),表示同意建立連接(第二次)
(5)客戶端收到客戶端發的SYN+ACK段,表明客戶端連接已建立成功,進入ESTABLISHED狀態,從connect()。客戶端再向服務器發送一個ACK段,服務器收到后則服務器端連接也建立成功,服務器也進入ESTABLISHED狀態。
數據傳輸
(1)連接建立成功后,在同一連接、同一時刻,通信雙方可同時寫數據(全雙工)
(2)服務器端從accept()返回后調用read()開始讀數據,若沒有數據則阻塞等待
(3)客戶端調用write()向服務器發送數據請求,客戶端收到之后調用read()處理請求,此過程服務器調用read()阻塞等待
(4)服務器調用write()將處理好的請求發送給客戶端,再次調用read()等待下一個請求
(5)客戶端收到后從read()返回,發送下一條請求,如此循環下去
斷開連接
(1)沒有數據處理了,則客戶端調用close()關閉連接,給服務器端發送一個斷開連接請求FIN段(第一次)
(2)服務器收到客戶端的FIN段,給客戶端發送一個確認應答ACK段表明同意斷開連接,客戶端收到ACK段并調用read()返回0,表明客戶端連接已斷開(第二次)
(3)read()返回0之后,服務器知道客戶端已斷開連接,它也調用close()關閉連接,給客戶端發送一個斷開連接請求FIN段(第三次)
(4)客戶端接收到服務器端發送的FIN段,給服務器一個確認應答ACK段,表明同意斷開連接。客戶端進入TIME_WAIT狀態,服務器收到客戶端的ACK后則服務器斷開連接。
二、編寫網游客戶端
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Net;
using System.Net.Sockets;
using System.Media;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;namespace WinFormsApp1
{public partial class Form1 : Form{public Form1(){InitializeComponent();}private NetworkStream stream
;private TcpClient tcpClient
;SoundPlayer player
= new SoundPlayer("D:/Fuchikami/nene/Lopu$ - So Cute~.mp3");Socket socket_send
;void send_stream(string str
){System
.Text
.Encoding
.RegisterProvider(System
.Text
.CodePagesEncodingProvider
.Instance
);System.Text.Encoding GBK
= System
.Text
.Encoding
.GetEncoding("GBK");byte[] buffer
= GBK
.GetBytes(str
+ "\n");stream
.Write(buffer
, 0, buffer
.Length
);}void receive_stream(){byte[] receive_data
= new byte[1024];System
.Text
.Encoding
.RegisterProvider(System
.Text
.CodePagesEncodingProvider
.Instance
);System.Text.Encoding GBK
= System
.Text
.Encoding
.GetEncoding("GBK");if (stream
.CanRead
){int len
= stream
.Read(receive_data
, 0, receive_data
.Length
);string msg
= GBK
.GetString(receive_data
, 0, receive_data
.Length
);string str
= "\r\n";char[] str1
= str
.ToCharArray();string[] messy_code
= { "??[2J ", "[5m", "[44m", "[37;0m", "[1;33m", "[1;32m", "[1;31m" };string[] msg1
= msg
.Split(str1
);for (int j
= 0; j
< msg1
.Length
; j
++){msg1
[j
] = msg1
[j
].Replace(messy_code
[0], " ");msg1
[j
] = msg1
[j
].Replace(messy_code
[1], " ");msg1
[j
] = msg1
[j
].Replace(messy_code
[2], " ");msg1
[j
] = msg1
[j
].Replace(messy_code
[3], " ");msg1
[j
] = msg1
[j
].Replace(messy_code
[4], " ");msg1
[j
] = msg1
[j
].Replace(messy_code
[5], " ");msg1
[j
] = msg1
[j
].Replace(messy_code
[6], " ");listBox1
.Items
.Add(msg1
[j
]);}}}private void button1_Click(object sender
, EventArgs e
){}private void pictureBox1_Click(object sender
, EventArgs e
){}private void button2_Click(object sender
, EventArgs e
){tcpClient
= new TcpClient();socket_send
= new Socket(AddressFamily
.InterNetwork
, SocketType
.Stream
, ProtocolType
.Tcp
);IPEndPoint point
= new IPEndPoint(IPAddress
.Parse("10.1.230.74"), 3900);socket_send
.Connect(point
);try{tcpClient
.Connect("10.1.230.74", 3900);listBox1
.Items
.Add("連接成功");stream
= tcpClient
.GetStream();receive_stream();}catch{listBox1
.Items
.Add("服務器未啟動");}}private void listBox1_SelectedIndexChanged(object sender
, EventArgs e
){if (tcpClient
.Connected
){string action
= textBox1
.Text
.ToString();listBox1
.Items
.Add("輸入的信息為:" + action
);send_stream(action
);receive_stream();}else{listBox1
.Items
.Add("連接已斷開");}}private void button3_Click(object sender
, EventArgs e
){if (stream
!= null){stream
.Close();tcpClient
.Close();socket_send
.Close();}listBox1
.Items
.Add("退出游戲");}private void button4_Click(object sender
, EventArgs e
){player
.Load();player
.Play();}}
}
總結
以上是生活随笔為你收集整理的C#游戏客户端编程的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。