正文

VB使用WinSock设计网络五子棋2005-09-29 14:17:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/iamben250/5452.html

分享到:

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 

阅读(4235) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册