導航:首頁 > 網路設置 > 網路游戲設計中socket之間數據共享

網路游戲設計中socket之間數據共享

發布時間:2022-08-10 09:06:57

❶ socket通信原理

socket通信原理是一種「打開—讀/寫—關閉」模式的實現,伺服器和客戶端各自維護一個「文件」,在建立連接打開後,可以向文件寫入內容供對方讀取或者讀取對方內容,通訊結束時關閉文件。

Socket在應用層和傳輸層之間的一個抽象層,它把 TCP/IP 層復雜的操作抽象為幾個簡單的介面,供應用層調用實現進程在網路中的通信。Socket 起源於 UNIX,在 UNIX 一切皆文件的思想下,進程間通信就被冠名為文件描述符(file descriptor)。

Socket 保證了不同計算機之間的通信,也就是網路通信。對於網站,通信模型是伺服器與客戶端之間的通信。兩端都建立了一個 Socket 對象,然後通過 Socket 對象對數據進行傳輸。通常伺服器處於一個無限循環,等待客戶端的連接。

(1)網路游戲設計中socket之間數據共享擴展閱讀

SOCK_STREAM類型的套介面為全雙向的位元組流。對於流類套介面,在接收或發送數據前必需處於已連接狀態。用connect()調用建立與另一套介面的連接,連接成功後,即可用send()和recv()傳送數據。當會話結束後,調用closesocket()。帶外數據根據規定用send()和recv()來接收。

實現SOCK_STREAM類型套介面的通訊協議保證數據不會丟失也不會重復。如果終端協議有緩沖區空間,且數據不能在一定時間成功發送,則認為連接中斷,其後續的調用也將以WSAETIMEOUT錯誤返回。

SOCK_DGRAM類型套介面允許使用sendto()和recvfrom()從任意埠發送或接收數據報。如果這樣一個套介面用connect()與一個指定埠連接,則可用send()和recv()與該埠進行數據報的發送與接收。

❷ 誅仙游戲跨服伺服器是怎麼實現數據互通的

至於如何實現多台伺服器之間的信息共享,有很多方法可以實現。
一般情況下比如我們設計一個後端服務,包括多個伺服器:資料庫伺服器,web伺服器,文件伺服器、緩存伺服器等的通信,一般是通過socket來設計專門的通信協議,因為比較高效。比如MySQL,MSSQL等也都是有知名的專用埠號。這個場景大多是在一個內網中,所以通信效率一般沒問題。
誅夢仙緣,天涯路遠,唯有情深不負。完美世界游戲旗下經典仙俠網游《誅仙3》全新版本「情海洄夢」現已傾情上線!空桑山又起劫難,各路豪傑齊進發,再回相遇之地重溫舊夢;新人物傳揭開小白前塵故事;還有新奇遇等,超多活動內容!我們期待在誅仙與你相逢。

❸ C語言socket編程怎麼實現2個客戶端之間通信

  1. 網路的Socket數據傳輸是一種特殊的I/O,Socket也是一種文件描述符。Socket也具有一個類似於打開文件的函數調用Socket(),該函數返回一個整型的Socket描述符,隨後的連接建立、數據傳輸等操作都是通過該Socket實現的。

  2. 下面用Socket實現一個windows下的c語言socket通信例子,這里我們客戶端傳遞一個字元串,伺服器端進行接收。

    【伺服器端】
    #include"stdafx.h"
    #include<stdio.h>
    #include<winsock2.h>
    #include<winsock2.h>
    #defineSERVER_PORT5208//偵聽埠
    voidmain()
    {
    WORDwVersionRequested;
    WSADATAwsaData;
    intret,nLeft,length;
    SOCKETsListen,sServer;//偵聽套接字,連接套接字
    structsockaddr_insaServer,saClient;//地址信息
    char*ptr;//用於遍歷信息的指針
    //WinSock初始化
    wVersionRequested=MAKEWORD(2,2);//希望使用的WinSockDLL的版本
    ret=WSAStartup(wVersionRequested,&wsaData);
    if(ret!=0)
    {
    printf("WSAStartup()failed! ");
    return;
    }
    //創建Socket,使用TCP協議
    sListen=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    if(sListen==INVALID_SOCKET)
    {
    WSACleanup();
    printf("socket()faild! ");
    return;
    }
    //構建本地地址信息
    saServer.sin_family=AF_INET;//地址家族
    saServer.sin_port=htons(SERVER_PORT);//注意轉化為網路位元組序
    saServer.sin_addr.S_un.S_addr=htonl(INADDR_ANY);//使用INADDR_ANY指示任意地址

    //綁定
    ret=bind(sListen,(structsockaddr*)&saServer,sizeof(saServer));
    if(ret==SOCKET_ERROR)
    {
    printf("bind()faild!code:%d ",WSAGetLastError());
    closesocket(sListen);//關閉套接字
    WSACleanup();
    return;
    }

    //偵聽連接請求
    ret=listen(sListen,5);
    if(ret==SOCKET_ERROR)
    {
    printf("listen()faild!code:%d ",WSAGetLastError());
    closesocket(sListen);//關閉套接字
    return;
    }

    printf("Waitingforclientconnecting! ");
    printf("Tips:Ctrl+ctoquit! ");
    //阻塞等待接受客戶端連接
    while(1)//循環監聽客戶端,永遠不停止,所以,在本項目中,我們沒有心跳包。
    {
    length=sizeof(saClient);
    sServer=accept(sListen,(structsockaddr*)&saClient,&length);
    if(sServer==INVALID_SOCKET)
    {
    printf("accept()faild!code:%d ",WSAGetLastError());
    closesocket(sListen);//關閉套接字
    WSACleanup();
    return;
    }
    charreceiveMessage[5000];
    nLeft=sizeof(receiveMessage);
    ptr=(char*)&receiveMessage;
    while(nLeft>0)
    {
    //接收數據
    ret=recv(sServer,ptr,5000,0);
    if(ret==SOCKET_ERROR)
    {
    printf("recv()failed! ");
    return;
    }
    if(ret==0)//客戶端已經關閉連接
    {
    printf("Clienthasclosedtheconnection ");
    break;
    }
    nLeft-=ret;
    ptr+=ret;
    }
    printf("receivemessage:%s ",receiveMessage);//列印我們接收到的消息。

    }
    //closesocket(sListen);
    //closesocket(sServer);
    //WSACleanup();
    }
    【客戶端】
    #include"stdafx.h"
    #include<stdio.h>
    #include<stdlib.h>
    #include<winsock2.h>
    #defineSERVER_PORT5208//偵聽埠
    voidmain()
    {
    WORDwVersionRequested;
    WSADATAwsaData;
    intret;
    SOCKETsClient;//連接套接字
    structsockaddr_insaServer;//地址信息
    char*ptr;
    BOOLfSuccess=TRUE;
    //WinSock初始化
    wVersionRequested=MAKEWORD(2,2);//希望使用的WinSockDLL的版本
    ret=WSAStartup(wVersionRequested,&wsaData);
    if(ret!=0)
    {
    printf("WSAStartup()failed! ");
    return;
    }
    //確認WinSockDLL支持版本2.2
    if(LOBYTE(wsaData.wVersion)!=2||HIBYTE(wsaData.wVersion)!=2)
    {
    WSACleanup();
    printf("InvalidWinSockversion! ");
    return;
    }
    //創建Socket,使用TCP協議
    sClient=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    if(sClient==INVALID_SOCKET)
    {
    WSACleanup();
    printf("socket()failed! ");
    return;
    }
    //構建伺服器地址信息
    saServer.sin_family=AF_INET;//地址家族
    saServer.sin_port=htons(SERVER_PORT);//注意轉化為網路節序
    saServer.sin_addr.S_un.S_addr=inet_addr("192.168.1.127");
    //連接伺服器
    ret=connect(sClient,(structsockaddr*)&saServer,sizeof(saServer));
    if(ret==SOCKET_ERROR)
    {
    printf("connect()failed! ");
    closesocket(sClient);//關閉套接字
    WSACleanup();
    return;
    }


    charsendMessage[]="hellothisisclientmessage!";
    ret=send(sClient,(char*)&sendMessage,sizeof(sendMessage),0);
    if(ret==SOCKET_ERROR)
    {
    printf("send()failed! ");
    }
    else
    printf("clientinfohasbeensent!");
    closesocket(sClient);//關閉套接字
    WSACleanup();
    }

❹ 有關網路游戲伺服器的問題

IOCP全稱I/O Completion Port,中文譯為I/O完成埠。IOCP是一個非同步I/O的API,它可以高效地將I/O事件通知給應用程序。與使用select()或是其它非同步方法不同的是,一個套接字[socket]與一個完成埠關聯了起來,然後就可繼續進行正常的Winsock操作了。然而,當一個事件發生的時候,此完成埠就將被操作系統加入一個隊列中。然後應用程序可以對核心層進行查詢以得到此完成埠。
這里我要對上面的一些概念略作補充,在解釋[完成]兩字之前,我想先簡單的提一下同步和非同步這兩個概念,邏輯上來講做完一件事後再去做另一件事就是同步,而同時一起做兩件或兩件以上事的話就是非同步了。你也可以拿單線程和多線程來作比喻。但是我們一定要將同步和堵塞,非同步和非堵塞區分開來,所謂的堵塞函數諸如accept(…),當調用此函數後,此時線程將掛起,直到操作系統來通知它,「HEY兄弟,有人連進來了」,那個掛起的線程將繼續進行工作,也就符合」生產者-消費者」模型。堵塞和同步看上去有兩分相似,但卻是完全不同的概念。大家都知道I/O設備是個相對慢速的設備,不論列印機,數據機,甚至硬碟,與CPU相比都是奇慢無比的,坐下來等I/O的完成是一件不甚明智的事情,有時候數據的流動率非常驚人,把數據從你的文件伺服器中以Ethernet速度搬走,其速度可能高達每秒一百萬位元組,如果你嘗試從文件伺服器中讀取100KB,在用戶的眼光來看幾乎是瞬間完成,但是,要知道,你的線程執行這個命令,已經浪費了10個一百萬次CPU周期。所以說,我們一般使用另一個線程來進行I/O。重疊IO[overlappedI/O]是Win32的一項技術,你可以要求操作系統為你傳送數據,並且在傳送完畢時通知你。這也就是[完成]的含義。這項技術使你的程序在I/O進行過程中仍然能夠繼續處理事務。事實上,操作系統內部正是以線程來完成overlapped I/O。你可以獲得線程所有利益,而不需要付出什麼痛苦的代價。
完成埠中所謂的[埠]並不是我們在TCP/IP中所提到的埠,可以說是完全沒有關系。我到現在也沒想通一個I/O設備[I/ODevice]和埠[IOCP中的Port]有什麼關系。估計這個埠也迷惑了不少人。IOCP只不過是用來進行讀寫操作,和文件I/O倒是有些類似。既然是一個讀寫設備,我們所能要求它的只是在處理讀與寫上的高效。

❺ Linux下Socket編程 怎樣實現客戶端之間互相通信

  1. 網路的Socket數據傳輸是一種特殊的I/O,Socket也是一種文件描述符。Socket也具有一個類似於打開文件的函數調用Socket(),該函數返回一個整型的Socket描述符,隨後的連接建立、數據傳輸等操作都是通過該Socket實現的。

  2. 下面用Socket實現一個windows下的c語言socket通信例子,這里我們客戶端傳遞一個字元串,伺服器端進行接收。

【伺服器端】
#include"stdafx.h"
#include<stdio.h>
#include<winsock2.h>
#include<winsock2.h>
#defineSERVER_PORT5208//偵聽埠
voidmain()
{
WORDwVersionRequested;
WSADATAwsaData;
intret,nLeft,length;
SOCKETsListen,sServer;//偵聽套接字,連接套接字
structsockaddr_insaServer,saClient;//地址信息
char*ptr;//用於遍歷信息的指針
//WinSock初始化
wVersionRequested=MAKEWORD(2,2);//希望使用的WinSockDLL的版本
ret=WSAStartup(wVersionRequested,&wsaData);
if(ret!=0)
{
printf("WSAStartup()failed! ");
return;
}
//創建Socket,使用TCP協議
sListen=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(sListen==INVALID_SOCKET)
{
WSACleanup();
printf("socket()faild! ");
return;
}
//構建本地地址信息
saServer.sin_family=AF_INET;//地址家族
saServer.sin_port=htons(SERVER_PORT);//注意轉化為網路位元組序
saServer.sin_addr.S_un.S_addr=htonl(INADDR_ANY);//使用INADDR_ANY指示任意地址

//綁定
ret=bind(sListen,(structsockaddr*)&saServer,sizeof(saServer));
if(ret==SOCKET_ERROR)
{
printf("bind()faild!code:%d ",WSAGetLastError());
closesocket(sListen);//關閉套接字
WSACleanup();
return;
}

//偵聽連接請求
ret=listen(sListen,5);
if(ret==SOCKET_ERROR)
{
printf("listen()faild!code:%d ",WSAGetLastError());
closesocket(sListen);//關閉套接字
return;
}

printf("Waitingforclientconnecting! ");
printf("Tips:Ctrl+ctoquit! ");
//阻塞等待接受客戶端連接
while(1)//循環監聽客戶端,永遠不停止,所以,在本項目中,我們沒有心跳包。
{
length=sizeof(saClient);
sServer=accept(sListen,(structsockaddr*)&saClient,&length);
if(sServer==INVALID_SOCKET)
{
printf("accept()faild!code:%d ",WSAGetLastError());
closesocket(sListen);//關閉套接字
WSACleanup();
return;
}
charreceiveMessage[5000];
nLeft=sizeof(receiveMessage);
ptr=(char*)&receiveMessage;
while(nLeft>0)
{
//接收數據
ret=recv(sServer,ptr,5000,0);
if(ret==SOCKET_ERROR)
{
printf("recv()failed! ");
return;
}
if(ret==0)//客戶端已經關閉連接
{
printf("Clienthasclosedtheconnection ");
break;
}
nLeft-=ret;
ptr+=ret;
}
printf("receivemessage:%s ",receiveMessage);//列印我們接收到的消息。

}
//closesocket(sListen);
//closesocket(sServer);
//WSACleanup();
}
【客戶端】
#include"stdafx.h"
#include<stdio.h>
#include<stdlib.h>
#include<winsock2.h>
#defineSERVER_PORT5208//偵聽埠
voidmain()
{
WORDwVersionRequested;
WSADATAwsaData;
intret;
SOCKETsClient;//連接套接字
structsockaddr_insaServer;//地址信息
char*ptr;
BOOLfSuccess=TRUE;
//WinSock初始化
wVersionRequested=MAKEWORD(2,2);//希望使用的WinSockDLL的版本
ret=WSAStartup(wVersionRequested,&wsaData);
if(ret!=0)
{
printf("WSAStartup()failed! ");
return;
}
//確認WinSockDLL支持版本2.2
if(LOBYTE(wsaData.wVersion)!=2||HIBYTE(wsaData.wVersion)!=2)
{
WSACleanup();
printf("InvalidWinSockversion! ");
return;
}
//創建Socket,使用TCP協議
sClient=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(sClient==INVALID_SOCKET)
{
WSACleanup();
printf("socket()failed! ");
return;
}
//構建伺服器地址信息
saServer.sin_family=AF_INET;//地址家族
saServer.sin_port=htons(SERVER_PORT);//注意轉化為網路節序
saServer.sin_addr.S_un.S_addr=inet_addr("192.168.1.127");
//連接伺服器
ret=connect(sClient,(structsockaddr*)&saServer,sizeof(saServer));
if(ret==SOCKET_ERROR)
{
printf("connect()failed! ");
closesocket(sClient);//關閉套接字
WSACleanup();
return;
}


charsendMessage[]="hellothisisclientmessage!";
ret=send(sClient,(char*)&sendMessage,sizeof(sendMessage),0);
if(ret==SOCKET_ERROR)
{
printf("send()failed! ");
}
else
printf("clientinfohasbeensent!");
closesocket(sClient);//關閉套接字
WSACleanup();
}

❻ 如何在socket的基礎上實現兩台主機之間的通訊

用VB5中WinSock控制項編寫網上聊天程序

Sockets是在Unix系統上提出來的,一開始主要是用於本地通訊,但很快就應用到C/S體繫上。MicroSoft公司在此基礎上創建了WinSock控制項,專門用於Windows介面,與Sockets完全兼容。Winsock控制項對用戶來說是不可見的,它提供了訪問 TCP 和 UDP 網路服務的方便途徑。Microsoft Access、Visual Basic、Visual C++ 或 Visual FoxPro 的開發人員都可使用它。為編寫客戶或伺服器應用程序,不必了解 TCP 的細節或調用低級的 Winsock APIs。通過設置控制項的屬性並調用其方法就可輕易連接到一台遠程機器上去,並且還可雙向交換數據。下面就利用VB5中的WinSock控制項編寫一個網上聊天程序。

一)網路通信協議的基礎和選擇

1.1 TCP(數據傳輸協議)基礎

數據傳輸協議允許創建和維護與遠程計算機的連接。連接兩台計算機就可彼此進行數據傳輸。
如果創建客戶應用程序,就必須知道伺服器計算機名或者 IP 地址(RemoteHost 屬性),還要知道進行「偵聽」的埠(RemotePort 屬性),然後調用 Connect 方法。
如果創建伺服器應用程序,就應設置一個收聽埠(LocalPort 屬性)並調用 Listen 方法。當客戶計算機需要連接時就會發生 ConnectionRequest 事件。為了完成連接,可調用 ConnectionRequest 事件內的 Accept 方法。
建立連接後,任何一方計算機都可以收發數據。為了發送數據,可調用 SendData 方法。當接收數據時會發生 DataArrival 事件。調用 DataArrival 事件內的 GetData 方法就可獲取數據。

1.2 UDP(用戶數據文報協議)基礎

用戶數據文報協議 (UDP) 是一個無連接協議。跟 TCP 的操作不同,計算機並不建立連接。另外 UDP 應用程序可以是客戶機,也可以是伺服器。
為了傳輸數據,首先要設置客戶計算機的 LocalPort 屬性。然後,伺服器計算機只需將 RemoteHost 設置為客戶計算機的 Internet 地址,並將 RemotePort 屬性設置為跟客戶計算機的 LocalPort 屬性相同的埠,並調用 SendData 方法來著手發送信息。於是,客戶計算機使用 DataArrival 事件內的 GetData 方法來獲取已發送的信息。

1.3 選擇通訊協議

在使用 WinSock 控制項時,首先需要考慮使用什麼協議。可以使用的協議包括 TCP 和 UDP。兩種協議之間的重要區別在於它們的連接狀態:
TCP 協議是有連接的協議,可以將它同電話系統相比。在開始數據傳輸之前,用戶必須先建立連接。
UDP 協議是一種無連接協議,兩台計算機之間的傳輸類似於傳遞郵件:消息從一台計算機發送到另一台計算機,但是兩者之間沒有明確的連接。另外,單次傳輸的最大數據量取決於具體的網路。

到底選擇哪一種協議通常是由需要創建的應用程序決定的。下面的幾個問題將有助於選擇適宜的協議:

1. 在收發數據的時候,應用程序是否需要得到客戶端或者伺服器的確認信息?如果需要,使用 TCP 協議,在收發數據之前先建立明確的連接。

2. 數據量是否特別大(例如圖象與聲音文件)?在連接建立之後,TCP 協議將維護連接並確保數據的完整性。不過,這種連接需要更多的計算資源,因而是比較「昂貴」的。

3. 數據發送是間歇的,還是在一個會話內?例如,如果應用程序在某個任務完成的時候需要通知某個計算機,UDP 協議是更適宜的。UDP 協議適合發送少量的數據。

通訊協議的選擇是通過設置WinSock的Protocol屬性來實現的。下面選擇TCP通訊協議編寫網上聊天程序,在此之前必須知道一個極其重要的參數---伺服器端的IP地址或計算機名。

二)確定計算機的名字

1. 在計算機的桌面上,右鍵單擊「網上鄰居」。

2. 選擇「屬性」。

3. 單擊「標識」選項卡。

4. 在「計算機名稱」框中可以找到計算機的名稱。

確定計算機的 IP地址

1. 單擊「任務條」上的「啟動」。

2. 選擇「運行」。

3. 若伺服器端操作系統為win95則在「打開」中填入「winipcfg」,若伺服器端操作系統為winnt則在「打開」中填入「ipconfig」。

4. 按下「確定」鍵。

上面找到的計算機名稱或IP地址可以作為WinSock的RemoteHost 屬性的值。

三) winsock控制項的State屬性。

state 屬性的設置值是: 常 數
值 描 述

sckclosed 0 預設的。關閉
sckopen 1 打開
scklistening 2 偵聽
sckconnectionpending 3 連接掛起
sckresolvinghost 4 識別主機
sckhostresolved 5 已識別主機
sckconnecting 6 正在連接
sckconnected 7 已連接
sckclosing 8 同級人員正在關閉連接
sckerror 9 錯誤

下面主要要用到sckClosed.sckConnected兩個State屬性的值。

四)網上聊天程序的編制

4.1 程序中伺服器端所起的作用。

從圖示中可以看到伺服器端的兩個winsock控制項之間並不存在直接的通訊,同時sckServer1和sckClient2及sckServer2和sckClient1之間是不能直接通訊的。這也即是說若sckClient1向sckClient2發出信息,信息首先被sckServer1接受,sckServer1再將信息傳給程序的信息處理部分,信息處理部分再將處理好的信息傳給sckServer2,再由sckServer2傳給sckClient2。反之亦然。那麼伺服器端的信息處理部分又進行什麼工作呢?

1. 對通訊的通道數作一些限制。

2. 對使用後已關閉的通道,必須能夠重新使用以節省資源。

3. 必須對所傳遞的數據包信息作甑別,從而作出不同的處理。

通過解開數據的包頭就可區分不同的信息。

網上聊天有兩種方式:第一種,以廣播方式;第二種,以點對點的方式。廣播方式即所有客戶都能收到某一客戶發出的信息。點對點的方式即想說「悄悄話」的一對客戶專門開辟了一間談話的「小屋」,別的客戶不能「聽」到他們的談話。在下面的程序中將看到如何利用數據的不同包頭來區分用戶是想以廣播方式還是以點對點的方式進行談話的(點對點方式數據的包頭為「PT」,廣播方式則無包頭)。

4.2 客戶端的程序

1. 在客戶端創建一個新的工程將其命名為「ClientPrj」

2. 將預設窗體命名為 frmClient。

3. 將窗體的標題改為「Client」。

4. 在窗體中添加一個 WinSock 控制項,並將其命名為 tcpClient。

5. 在 frmClient 中添加一個ListBox 控制項。將其命名為lstReceive。

6. 在 frmClient 中添加一個 TextBox 控制項。將其命名為 txtSend。

7. 在窗體上放兩個 CommandButton 控制項,並將其命名為 cmdConnect和cmdSent。

8. 將cmdConnect控制項的標題改為 Connect, 將cmdSent控制項的標題改為 Sent。

9. 在窗體中添加如下的代碼。

Private Sub cmdConnect_Click()

On Error GoTo ErrorPro

sckClient.Connect

Exit Sub

ErrorPro:

MsgBox "伺服器未開或網路出錯!"

End

End Sub

Private Sub cmdSent_Click()

sckClient.SendData txtSent.Text

End Sub

Private Sub Form_Load()

' RemoteComputerName為伺服器端的計算機名或IP地址。

sckClient.RemoteHost = "RemoteComputerName"

sckClient.RemotePort = 1000

End Sub

Private Sub sckClient_Close()

MsgBox "伺服器通道已關閉!"

End

End Sub

Private Sub sckClient_Connect()

MsgBox "連接成功!"

cmdConnect.Enabled = False

End Sub

Private Sub sckClient_DataArrival(ByVal bytesTotal As Long)

Dim s As String

sckClient.GetData s

lstReceive.AddItem s

End Sub

Private Sub sckClient_Error(ByVal Number As Integer, Description As String, ByVal Scode As Long, _ ByVal Source As String, ByVal HelpFile As String, ByVal HelpContext As Long, CancelDisplay As Boolean)

sckClient.Close

cmdConnect.Enabled = True

End Sub

4.3 伺服器端的程序

1. 在伺服器端創建一個新的工程將其命名為「ServerPrj」。

2. 將預設窗體命名為「frmServer」。

3. 在窗體中添加一個ListBox控制項,將其命名為「lstReceive」。

4. 在窗體中添加三個WinSock控制項,將其分別命名為「sckListen」,sckBusy和「sckServer」並將「sckServer」的「Index」屬性設置為0。

5. 在窗體中添加如下代碼.。

'最大通道數

Private MaxChan As Integer

Private Sub Form_Load()

Dim i As Integer

MaxChan = 10

For i = 1 To MaxChan - 1

Load sckServer(i)

Next i

sckListen.LocalPort = 1000

sckListen.Listen

End Sub

Private Sub sckBusy_Close()

sckBusy.Close

End Sub

Private Sub sckBusy_DataArrival(ByVal bytesTotal As Long)

sckBusy.SendData "伺服器忙,請稍後再連接!"

DoEvents

End Sub

Private Sub sckListen_ConnectionRequest(ByVal requestID As Long)

Dim i As Integer

'決定由哪一Winsock接受請求

For i = 0 To MaxChan - 1

If sckServer(i).State = 0 Then

Exit For

End If

Next i

If sckServer(i).State = 0 Then

sckServer(i).Accept requestID

Exit Sub

End If

'如果所有Winsock都用完則由專門的「忙」Winsock接受請求,以免用戶要求得不到響應

sckBusy.Close

sckBusy.Accept requestID

End Sub

Private Sub sckListen_Error(ByVal Number As Integer, Description As String, ByVal Scode As Long, _ ByVal Source As String, ByVal HelpFile As String, ByVal HelpContext As Long, CancelDisplay As Boolean)

sckListen.Close

sckListen.LocalPort = 1000

sckListen.Listen

End Sub

Private Sub sckServer_Close(Index As Integer)

sckServer(Index).Close

End Sub

Private Sub sckServer_DataArrival(Index As Integer, ByVal bytesTotal As Long)

Dim s As String

Dim i As Integer

sckServer(Index).GetData s

If UCase(Left(Trim(s), 2)) = "PT" Then '判斷是否為悄悄話,點對點方式

If IsNumeric(Mid(Trim(s), 3, 1)) Then

i = Mid(Trim(s), 3, 1)

sckServer(i).SendData "Channel " & Index & " " & Right(Trim(s), Len(Trim(s)) - 3)

DoEvents

End If

Else '廣播方式

For i = 0 To MaxChan - 1

'利用winsock的State屬性給所有連接在伺服器上的客戶發消息

If sckServer(i).State = 7 Then

sckServer(i).SendData "Channel " & Index & " " & Trim(s)

DoEvents

End If

Next i

End If

lstReceive.AddItem "Channel " & Index & " " & Trim(s)

End Sub

Private Sub sckServer_Error(Index As Integer, ByVal Number As Integer, Description As String, _

ByVal Scode As Long, ByVal Source As String, ByVal HelpFile As String, ByVal HelpContext As _

Long, CancelDisplay As Boolean)

sckServer(Index).Close

End Sub

從程序中可以看到:第一,程序中限制了通道數(10路)。第二,通過判斷WinSock控制項的State屬性是否為0(關閉狀態),來重新使用已關閉的WinSock控制項。第三,通過給WinSock控制項傳遞的信息加上包頭,來對信息進行不同的處理(程序中若信息前加上了「PT"(Private Talk)+"通道數」的包頭,由此就知道客戶想要同擁有此「通道數」的另一客戶進行「悄悄話」,否則就以廣播方式將信息發給所有客戶)。

五) 結束語

WinSock控制項不僅僅是用來編制網上聊天程序,而且可以用來編制各種網路游戲或網路通信程序。實際上WinSock控制項是編制各種C/S程序的利器。在實際使用中通常是將WinSock控制項封裝在Activex DLL(進程內)、Activex EXE(進程外)部件的類中(類中引用)來使用的。通過區分所傳信息前的不同的包頭,用RaiseEvent命令引發不同 的事件,再對事件分別進行處理。這樣不僅增加了程序的可調試性和安全性,而且更符合事件驅動編程方法的特點。

❼ Qt 2個線程共用1個Socket 分別收發數據可以嗎

1:socket句柄就是一個整型,是映射到系統句柄隊列裡面(你可以認為這個值是一個key,一個key對應一個系統的具體socket結構體),指針是無意義的,比方你創建了一個socket句柄值是10,你直接使用10在任何線程都是調用這個socket,這個映射過程是socket相關api內部完成的,是全局的。

2:多個線程共用一個socket分別處理收發是可以的,很多這樣的例子,一些網路IO模型就是一個部分線程負責收數據包,部分線程負責發響應包,但不要多個線程共用一個socket來收,這樣會導致問題。

3:你要多線程共享socket句柄,直接傳值就行了,不要傳引用和指針,不過注意socket關閉的同步處理。最好用一個對象來統一處理每個socket的打開和關閉,讀取和發送。所有線程拿著這個對象來操作socket,這樣socket的有效性判斷都在對象裡面處理。不然一個線程關閉了socket,子線程不知道繼續拿著這個句柄號在操作就會出問題。

❽ java 編程 網路游戲 socket

UDP只是Socket的一種協議,兩者都可以用到,但是ServerSocket是必須用到的,對你的作業,如果只是兩人對戰,必然一人是ServerSocket(主服務),另外一個是Socket(客戶端);如果多人的話,還需要建立單獨的伺服器,多個客戶端之間不直接通信,通過伺服器來通信。

❾ java網路版中國象棋Socket傳遞數據的問題

  1. 寫一個伺服器端作為中轉消息用,兩個客戶端同時連接到伺服器端上。

  2. 其中一個客戶端同時也作為伺服器。


作為伺服器的一方,

ServerSocket server=new ServerSocket(port);

Socket client=server.accept();//接收到連接之後

啟動一個線程負責接收來自客戶端的消息。

象棋初始化,開始游戲。


傳遞數據有很多類型,傳遞字元串,然後接收之後分析。

用:

BufferedOutputStream bo=new BufferedOutputStream(client.getOutputStream());

bo.write("hellow".getBytes());//發送字元串

bo.flush();//清空緩沖區

讀取就用相應的:

BufferedInputStream bi=new BufferedInputStream(client.getInputStream());

byte b[]=new byte[1024];

int len=bi.read(b);

String s1=new String(b,0,len);

閱讀全文

與網路游戲設計中socket之間數據共享相關的資料

熱點內容
網路共享中心沒有網卡 瀏覽:522
電腦無法檢測到網路代理 瀏覽:1374
筆記本電腦一天會用多少流量 瀏覽:581
蘋果電腦整機轉移新機 瀏覽:1376
突然無法連接工作網路 瀏覽:1064
聯通網路怎麼設置才好 瀏覽:1225
小區網路電腦怎麼連接路由器 瀏覽:1039
p1108列印機網路共享 瀏覽:1212
怎麼調節台式電腦護眼 瀏覽:701
深圳天虹蘋果電腦 瀏覽:938
網路總是異常斷開 瀏覽:612
中級配置台式電腦 瀏覽:997
中國網路安全的戰士 瀏覽:631
同志網站在哪裡 瀏覽:1413
版觀看完整完結免費手機在線 瀏覽:1459
怎樣切換默認數據網路設置 瀏覽:1110
肯德基無線網無法訪問網路 瀏覽:1286
光纖貓怎麼連接不上網路 瀏覽:1481
神武3手游網路連接 瀏覽:965
局網列印機網路共享 瀏覽:1000