VB使用WinSock设计网络五子棋 |
|
Visual Basic 6.0中文企业版为Windows环境下的网络开发提供了强大的工具,Winsock控件就是其中之一。利用 WinSock 控件可以与远程计算机建立连接,Winsock包含有用户数据文报协议 (UDP)和传输控制协议 (TCP)。可用这两种协议来建立客户与服务器应用程序来进行通数据交换。WinSock 控件解决了以往应用VB编程时网络中应用程序之间无法实现点对点通信的难题。用户仅通过设置属性并借助事件处理就能够轻而易举地连接到一个远程的计算机上,而且只用两个方法就可以实现数据交换其中Senddata方法用于发送数据;Getdata方法用来取数据。 一、Winsock的编程基础 1.TCP协议:TCP(Transfer Control Protocol)是传输控制协议的简称,是基于连接的协议,在数据传输之前必须先建立连接。通过TCP协议建立的是客户/服务器通信方式。 2.UDP协议: UDP(User Data Protocol)是用户数据文报协议的简称,两台计算机之间的传输类似于传递邮件;两者之间没有明确的连接,可作为服务器,也可作为客户机。 使用UDP协议建立对等通信和通过TCP建立客户/服务器通信的方法略有不同,它不需要建立客户和服务器,而是建立对等通信。 3. Winsock属性: LocalPort:返回或者设置所用到的本端口;如果指定的是端口 0,就使用一个随机端口。 Protocol:返回或设置Winsock所用的协议是TCP或UDP。 State:返回控件的状态,用枚举类型来表示。 4. Winsock方法: Listen:用于服务器程序,等待客户访问。 Connect:用于向远程主机发出连接请求 Accept:用于接受一个连接请求 Senddata: 此方法用于发送数据 Getdata: 用来取得接收到的数据 格式:Winsock对象.getdata 变量 [,数据类型 [,最大长度]] Close: 关闭当前连接 格式:Winsock对象.close 5.事件: DataArrival:新数据到达时出现;获取一个 GetData 调用中的全部数据。 ConnectionRequest:当远程计算机请求连接时接受连接请求。 SendComplete :在完成一个发送操作时出现 。 SendProgress :在发送数据期间出现 。 Close :当远程计算机关闭连接时出现。 二、网络五子棋设计思想 设计时,采用TCP协议来保证数据传输的可靠性。在欢迎登录界面中要求用户选择作为主机还是联机,用server变量来表示。如果作为主机的话,则进入侦听状态。假如有联机的话,则进入联机状态。 在下棋过程中,为了保存下过的棋子的位子使用了map数组,map数组初值为零,可以有1,2,3,4值,分别代表四种棋子图案,黑子,白子,黑红子,红子图案。黑红子分别代表刚下过的黑子,红子分别代表刚下过的白子。每下一棋子,均将棋盘按照map数组调用DrawScreen过程重画。并调用Gameover函数判断是否已经连成五子,如果返回非零,则说明已经连成五子,显示输赢结果。无论否已经连成五子,均将本步信息通过senddata传到对方。为了区分传送的是名字信息,请求联机信息,下的棋子信息,开新局请求信息,在发送信息的首部加上代号。 Private Sub Com1_Click(Index As Integer) Select Case Index Case 0 ’开始新局 Send "3" ResetGame ’如果本机主机的话,pic图片有效,可以下子否则无效。 If Server = 1 Then Pic1.Enabled = True Else Pic1.Enabled = False Case 1 ’重新联机 If Label2.Caption = "联机中" Then Send "4" DoEvents End If Winsock1.Close Label2.Caption = "尚未联机" ’加载联机欢迎窗体 Load Form2 Form2.Show Case 2 ’断开连接并结束运行 If Label2.Caption = "联机中" Then Send "4" DoEvents End If Winsock1.Close End End Select End Sub Private Sub Form_Unload(Cancel As Integer) If Label2.Caption = "联机中" Then Send "4" DoEvents End If Winsock1.Close End End Sub Private Sub Pic1_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single) If Button = 1 Then ’将屏幕坐标转换为棋盘坐标 sx = Fix(X / 21) + 1: sy = Fix(Y / 20) + 1 If map(sx, sy) <> 0 Then Exit Sub Call sndPlaySound("put.wav", 0) map(sx, sy) = Server DrawScreen a = GameOver(Server) If a = Server Then Label1(0).Caption = "你赢了" Win(Server) = Win(Server) + 1 If Server = 1 Then Lost(2) = Lost(2) + 1 Else Lost(1) = Lost(1) + 1 Form1.Label1(2).Caption = "战绩:" + Str(Win(1)) + "胜" + Str(Lost(1)) + "败" Form1.Label1(4).Caption = "战绩:" + Str(Win(2)) + "胜" + Str(Lost(2)) + "败" End If Send "1" + Chr(sx) + Chr(sy) Pic1.Enabled = False End If End Sub Private Sub Winsock1_ConnectionRequest(ByVal requestID As Long) If Winsock1.State <> sckClosed Then Winsock1.Close Winsock1.Accept requestID Label2.Caption = "联机中" Pic1.Enabled = True End Sub Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long) GetMyData bytesTotal End Sub Private Sub Winsock1_Connect() Label2.Caption = "联机中" Send "2" + Label1(3).Caption End Sub Private Sub Command1_Click() If Server = 1 Then ’自己作为主机 Form1.Winsock1.LocalPort = 5238 Form1.Winsock1.Listen Form1.Label1(1).Caption = "黑子:" + Text1.Text Form1.Label1(3).Caption = "" Form1.Label2.Caption = "等待加入中" Else ’自己作为联机 Form1.Winsock1.RemoteHost = Text2.Text Form1.Winsock1.RemotePort = 5238 Form1.Winsock1.LocalPort = 0 Form1.Winsock1.Connect Form1.Label1(1).Caption = "" Form1.Label1(3).Caption = "白子:" + Text1.Text Form1.Label2.Caption = "正在联机到主机" End If Form1.Label1(2).Caption = "战绩:" + Str(Win(1)) + "胜" + Str(Lost(1)) + "败" Form1.Label1(4).Caption = "战绩:" + Str(Win(2)) + "胜" + Str(Lost(2)) + "败" Form1.Show Form1.Pic1.Enabled = False Form1.Enabled = True Form2.Hide Unload Form2 ResetGame End Sub Private Sub Command2_Click() End End Sub Private Sub Form_Load() Form1.Enabled = False Text2.Text = Form1.Winsock1.LocalIP Server = 1 Win(1) = 0 Win(2) = 0 Lost(1) = 0 Lost(2) = 0 End Sub Private Sub Option1_Click() Label3.Caption = "你的主机IP" Text2.Text = Form1.Winsock1.LocalIP ’本机作为主机即server=1 Server = 1 End Sub Private Sub Option2_Click() Label3.Caption = "联机主机IP" Text2.Text = "0.0.0.0" ’本机作为联机即server=2 Server = 2 End Sub 公共模块 Declare Sub BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal X As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) Declare Function sndPlaySound Lib "Winmm.dll" Alias "sndPlaySoundA" (ByVal SoundName As String, ByVal Flags As Long) As Long Global Const srccopy = &HCC0020 Public map(1 To 15, 1 To 15) ’棋盘 Public Win(1 To 2), Lost(1 To 2) ’储存胜败次数 Public Server ’存放目前为主机或加入联机 ’主机=1 加入联机=2 Sub Main() Load Form1 Load Form2 Form1.Show Form2.Show End Sub Sub DrawScreen() ’画出棋子 ’map数组存放的是棋盘上棋子信息,Pic2图片存放四种棋子图案,黑子,白子,黑红子,红子图案 X = 3: Y = 2 For i = 1 To 15 For j = 1 To 15 ’map(i, j) = 1 表示应画黑子 If map(i, j) = 1 Then BitBlt Form1.Pic1.hDC, X, Y, 21, 20, Form1.Pic2.hDC, 0, 0, srccopy ’map(i, j) = 2 表示应画白子 If map(i, j) = 2 Then BitBlt Form1.Pic1.hDC, X, Y, 21, 20, Form1.Pic2.hDC, 21, 0, srccopy ’map(i, j) = 1 表示应画刚下后的黑子图案(黑红子) If map(i, j) = 3 Then BitBlt Form1.Pic1.hDC, X, Y, 21, 20, Form1.Pic2.hDC, 42, 0, srccopy ’map(i, j) = 1 表示应画刚下后的白子图案(红子) If map(i, j) = 4 Then BitBlt Form1.Pic1.hDC, X, Y, 21, 20, Form1.Pic2.hDC, 63, 0, srccopy Y = Y + 20 Next j Y = 2 X = X + 21 Next i Form1.Pic1.Refresh End Sub Sub Send(mydata As String) ’送出资料 Form1.Winsock1.SendData mydata End Sub Sub GetMyData(Size) ’接受资料 Dim mydata As String Form1.Winsock1.GetData mydata, vbString Select Case Mid(mydata, 1, 1) Case "1" ’棋子的资料 If Server = 1 Then s = 2 Else s = 1 Call sndPlaySound("put.wav", 0) sx = Asc(Mid(mydata, 2, 1)) sy = Asc(Mid(mydata, 3, 1)) map(sx, sy) = s + 2 DrawScreen map(sx, sy) = s a = GameOver(s) Form1.Pic1.Enabled = True If a = s Then Form1.Label1(0).Caption = "你输了" Form1.Pic1.Enabled = False Lost(Server) = Lost(Server) + 1 Win(s) = Win(s) + 1 Form1.Label1(2).Caption = "战绩:" + Str(Win(1)) + "胜" + Str(Lost(1)) + "败" Form1.Label1(4).Caption = "战绩:" + Str(Win(2)) + "胜" + Str(Lost(2)) + "败" End If Case "2" ’名字资料 If Server = 1 Then Form1.Label1(3).Caption = Mid(mydata, 2, Size - 1) Send "2" + Form1.Label1(1).Caption Else Form1.Label1(1).Caption = Mid(mydata, 2, Size - 1) End If Case "3" ’开新棋局送的资料 ResetGame Case "4" ’对方断线送的资料 Form1.Label2.Caption = "尚未联机" Form1.Pic1.Enabled = False Form1.Winsock1.Close Case Else End Select End Sub Function GameOver(a) ’判断是否连成五颗 For i = 1 To 11 For j = 1 To 11 If map(i, j) = a And map(i + 1, j + 1) = a And map(i + 2, j + 2) = a And map(i + 3, j + 3) = a And map(i + 4, j + 4) = a Then GameOver = a: Exit Function Next j Next i For i = 5 To 15 For j = 1 To 11 If map(i, j) = a And map(i - 1, j + 1) = a And map(i - 2, j + 2) = a And map(i - 3, j + 3) = a And map(i - 4, j + 4) = a Then GameOver = a: Exit Function Next j Next i For i = 1 To 15 For j = 5 To 11 If map(i, j) = a And map(i, j - 1) = a And map(i, j - 2) = a And map(i, j - 3) = a And map(i, j - 4) = a Then GameOver = a: Exit Function Next j Next i For i = 5 To 11 For j = 1 To 15 If map(i, j) = a And map(i + 1, j) = a And map(i + 2, j) = a And map(i + 3, j) = a And map(i + 4, j) = a Then GameOver = a: Exit Function Next j Next i GameOver = 0 End Function Sub ResetGame() ’开新棋局 Form1.Pic1.Cls For i = 1 To 15 For j = 1 To 15 map(i, j) = 0 Next j Next i End Sub |
正文
VB使用WinSock设计网络五子棋2005-09-29 14:17:00
【评论】 【打印】 【字体:大 中 小】 本文链接:http://blog.pfan.cn/iamben250/5452.html
阅读(4235) | 评论(0)
版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!
评论