生活随笔
收集整理的這篇文章主要介紹了
C#游戏客户端编程
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
目錄
- 一、TCP客戶端與服務(wù)器端通信
- 服務(wù)器初始化
- 建立連接
- 數(shù)據(jù)傳輸
- 斷開連接
- 二、編寫網(wǎng)游客戶端
一、TCP客戶端與服務(wù)器端通信
服務(wù)器初始化
(1)調(diào)用socket,創(chuàng)建文件描述符
(2)調(diào)用bind,將文件描述符與ip/port連接起來。若端口號已被占用,則bind失敗
(3)調(diào)用listen,聲明該文件描述符是服務(wù)器的一個(gè)文件描述符,為之后的accept做準(zhǔn)備
(4)調(diào)用accept,并處于阻塞狀態(tài),等待客戶端連接
建立連接
(1)調(diào)用socket,創(chuàng)建文件描述符
(2)調(diào)用connect,向服務(wù)器發(fā)起連接請求。
(3)connect會(huì)發(fā)送一個(gè)請求SYN段并阻塞等待服務(wù)器應(yīng)答(第一次)
(4)服務(wù)器收到SYN,會(huì)給客戶端發(fā)送一個(gè)確認(rèn)應(yīng)答的同時(shí)發(fā)送一個(gè)請求(SYN+ACK),表示同意建立連接(第二次)
(5)客戶端收到客戶端發(fā)的SYN+ACK段,表明客戶端連接已建立成功,進(jìn)入ESTABLISHED狀態(tài),從connect()。客戶端再向服務(wù)器發(fā)送一個(gè)ACK段,服務(wù)器收到后則服務(wù)器端連接也建立成功,服務(wù)器也進(jìn)入ESTABLISHED狀態(tài)。
數(shù)據(jù)傳輸
(1)連接建立成功后,在同一連接、同一時(shí)刻,通信雙方可同時(shí)寫數(shù)據(jù)(全雙工)
(2)服務(wù)器端從accept()返回后調(diào)用read()開始讀數(shù)據(jù),若沒有數(shù)據(jù)則阻塞等待
(3)客戶端調(diào)用write()向服務(wù)器發(fā)送數(shù)據(jù)請求,客戶端收到之后調(diào)用read()處理請求,此過程服務(wù)器調(diào)用read()阻塞等待
(4)服務(wù)器調(diào)用write()將處理好的請求發(fā)送給客戶端,再次調(diào)用read()等待下一個(gè)請求
(5)客戶端收到后從read()返回,發(fā)送下一條請求,如此循環(huán)下去
斷開連接
(1)沒有數(shù)據(jù)處理了,則客戶端調(diào)用close()關(guān)閉連接,給服務(wù)器端發(fā)送一個(gè)斷開連接請求FIN段(第一次)
(2)服務(wù)器收到客戶端的FIN段,給客戶端發(fā)送一個(gè)確認(rèn)應(yīng)答ACK段表明同意斷開連接,客戶端收到ACK段并調(diào)用read()返回0,表明客戶端連接已斷開(第二次)
(3)read()返回0之后,服務(wù)器知道客戶端已斷開連接,它也調(diào)用close()關(guān)閉連接,給客戶端發(fā)送一個(gè)斷開連接請求FIN段(第三次)
(4)客戶端接收到服務(wù)器端發(fā)送的FIN段,給服務(wù)器一個(gè)確認(rèn)應(yīng)答ACK段,表明同意斷開連接。客戶端進(jìn)入TIME_WAIT狀態(tài),服務(wù)器收到客戶端的ACK后則服務(wù)器斷開連接。
二、編寫網(wǎng)游客戶端
- 創(chuàng)建項(xiàng)目
- 基本界面設(shè)計(jì)
- 代碼
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("服務(wù)器未啟動(dòng)");}}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();}}
}
總結(jié)
以上是生活随笔為你收集整理的C#游戏客户端编程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。