第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

大家?guī)筒橄洛e(cuò)誤,為什么程序能夠運(yùn)行,客戶端發(fā)送的數(shù)據(jù)服務(wù)端收不道,運(yùn)行時(shí)客戶端和服務(wù)都再一臺(tái)機(jī)器上?

大家?guī)筒橄洛e(cuò)誤,為什么程序能夠運(yùn)行,客戶端發(fā)送的數(shù)據(jù)服務(wù)端收不道,運(yùn)行時(shí)客戶端和服務(wù)都再一臺(tái)機(jī)器上?

C++
楊__羊羊 2023-03-20 14:10:06
//Client端代碼#include <winsock2.h>#include <iostream.h>#include <stdio.h>void initClient();int main(){initClient();return 0;}void initClient(){WSADATA wsaData; int error=WSAStartup(MAKEWORD(2,2),&wsaData);if(error!=0){cout<<"初始化DLL失敗"<<endl;return;}if(LOBYTE(wsaData.wVersion)!=2 || HIBYTE(wsaData.wVersion)!=2){WSACleanup();cout<<"版本出錯(cuò)"<<endl;return;}SOCKET s=socket(AF_INET,SOCK_DGRAM,0);SOCKADDR_IN sockSend;sockSend.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");sockSend.sin_port=htons(4000);sockSend.sin_family=AF_INET;char buff[1024];strcpy(buff,"hello,it's the first!");int i=500;while(--i){int lenword;lenword=sendto(s,buff,strlen(buff)+1,0,(sockaddr *)&sockSend,sizeof(sockaddr));cout<<lenword<<","<<sockSend.sin_port<<":"<<sockSend.sin_addr.S_un.S_addr<<endl;}closesocket(s);WSACleanup();}//Server端代碼#include <winsock2.h>#include <iostream>#include <stdio.h>using namespace std;void initNet();int main(){initNet();return 0;}void initNet(){WSADATA wsaData; int error=WSAStartup(MAKEWORD(1,1),&wsaData);if(error!=0){cout<<"初始化DLL失敗"<<endl;return;}if(LOBYTE(wsaData.wVersion)!=1 || HIBYTE(wsaData.wVersion)!=1){WSACleanup();cout<<"版本出錯(cuò)"<<endl;return;}SOCKET s=socket(AF_INET,SOCK_DGRAM,0);SOCKADDR_IN sockSrc;sockSrc.sin_addr.S_un.S_addr=htonl(INADDR_ANY);sockSrc.sin_port=htons(4000);sockSrc.sin_family=AF_INET;bind(s,(SOCKADDR *)&sockSrc,sizeof(SOCKADDR));char recBuff[1024];memset(recBuff,0,1024);SOCKADDR_IN sockRec;int len=sizeof(SOCKADDR);int x=-1;cout<<sockSrc.sin_port<<":"<<sockSrc.sin_addr.S_un.S_addr<<endl;while(x==-1){x=recvfrom(s,recBuff,sizeof(recBuff),0,(sockaddr *)&sockRec,&len); }printf("the receive is:%s,%d \n",recBuff,x); closesocket(s);WSACleanup();}
查看完整描述

1 回答

?
慕工程0101907

TA貢獻(xiàn)1887條經(jīng)驗(yàn) 獲得超5個(gè)贊

通過建立雙套接字,可以很方便地實(shí)現(xiàn)全雙工網(wǎng)絡(luò)通信。 

1.套接字建立函數(shù): 

SOCKET socket(int family,int type,int protocol) 
對(duì)于UDP協(xié)議,寫為: 

SOCKRET s; 
s=socket(AF_INET,SOCK_DGRAM,0); 
或s=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP) 
為了建立兩個(gè)套接字,必須實(shí)現(xiàn)地址的重復(fù)綁定,即,當(dāng)一個(gè)套接字已經(jīng)綁定到某本地地址后,為了讓另一個(gè)套接字重復(fù)使用該地址,必須為調(diào)用bind()函數(shù)綁定第二個(gè)套接字之前,通過函數(shù)setsockopt()為該套接字設(shè)置SO_REUSEADDR套接字選項(xiàng)。通過函數(shù)getsockopt()可獲得套接字選項(xiàng)設(shè)置狀態(tài)。需要注意的是,兩個(gè)套接字所對(duì)應(yīng)的端口號(hào)不能相同。 此外,還涉及到套接字緩沖區(qū)的設(shè)置問題,按規(guī)定,每個(gè)區(qū)的設(shè)置范圍是:不小于512個(gè)字節(jié),大大于8k字節(jié),根據(jù)需要,文中選用了4k字節(jié)。 

2.套接字綁定函數(shù) 

int bind(SOCKET s,struct sockaddr_in*name,int namelen) 
s是剛才創(chuàng)建好的套接字,name指向描述通訊對(duì)象的結(jié)構(gòu)體的指針,namelen是該結(jié)構(gòu)體的長(zhǎng)度。該結(jié)構(gòu)體中的分量包括:IP地址(對(duì)應(yīng)name.sin_addr.s_addr)、端口號(hào)(name.sin_port)、地址類型(name.sin_family,一般都賦成AF_INET,表示是internet地址)。 

(1)IP地址的填寫方法:在全雙工通信中,要把用戶名對(duì)應(yīng)的點(diǎn)分表示法地址轉(zhuǎn)換成32位長(zhǎng)整數(shù)格式的IP地址,使用inet_addr()函數(shù)。 

(2)端口號(hào)是用于表示同一臺(tái)計(jì)算機(jī)不同的進(jìn)程(應(yīng)用程序),其分配方法有兩種:1)進(jìn)程可以讓系統(tǒng)為套接字自動(dòng)分配一端口號(hào),只要在調(diào)用bind前將端口號(hào)指定為0即可。由系統(tǒng)自動(dòng)分配的端口號(hào)位于1024~5000之間,而1~1023之間的任一TCP或UDP端口都是保留的,系統(tǒng)不允許任一進(jìn)程使用保留端口,除非其有效用戶ID是零(超級(jí)用戶)。 

2)進(jìn)程可為套接字指定一特定端口。這對(duì)于需要給套接字分配一眾所端口的服務(wù)器是很有用的。指定范圍為1024和65536之間??扇我庵付ā?nbsp;

在本程序中,對(duì)兩個(gè)套接字的端口號(hào)規(guī)定為2000和2001,前者對(duì)應(yīng)發(fā)送套接字,后者對(duì)應(yīng)接收套接字。 

端口號(hào)要從一個(gè)16位無符號(hào)數(shù)(u_short類型數(shù))從主機(jī)字節(jié)順序轉(zhuǎn)換成網(wǎng)絡(luò)字節(jié)順序,使用htons()函數(shù)。 

根據(jù)以上兩個(gè)函數(shù),可以給出雙套接字建立與綁定的程序片斷。 

//設(shè)置有關(guān)的全局變量 
SOCKET sr,ss; 
HPSTR sockBufferS,sockBufferR; 
HANDLE hSendData,hReceiveData; 
DWROD dwDataSize=1024*4; 
struct sockaddr_in therel.there2; 
#DEFINE LOCAL_HOST_ADDR 200.200.200.201 
#DEFINE REMOTE_HOST-ADDR 200.200.200.202 
#DEFINE LOCAL_HOST_PORT 2000 
#DEFINE LOCAL_HOST_PORT 2001 
//套接字建立函數(shù) 
BOOL make_skt(HWND hwnd) 

struct sockaddr_in here,here1; 
ss=socket(AF_INET,SOCK_DGRAM,0); 
sr=socket(AF_INET,SOCK_DGRAM,0); 
if((ss==INVALID_SOCKET)||(sr==INVALID_SOCKET)) 

MessageBox(hwnd,“套接字建立失敗!”,“”,MB_OK); 
return(FALSE); 

here.sin_family=AF_INET; 
here.sin_addr.s_addr=inet_addr(LOCAL_HOST_ADDR); 
here.sin_port=htons(LICAL_HOST_PORT); 
//another socket 
herel.sin_family=AF_INET; 
herel.sin_addr.s_addr(LOCAL_HOST_ADDR); 
herel.sin_port=htons(LOCAL_HOST_PORT1); 
SocketBuffer();//套接字緩沖區(qū)的鎖定設(shè)置 
setsockopt(ss,SOL_SOCKET,SO_SNDBUF,(char FAR*)sockBufferS,dwDataSize); 
if(bind(ss,(LPSOCKADDR)&here,sizeof(here))) 

MessageBox(hwnd,“發(fā)送套接字綁定失敗!”,“”,MB_OK); 
return(FALSE); 

setsockopt(sr SQL_SOCKET,SO_RCVBUF|SO_REUSEADDR,(char FAR*) 
sockBufferR,dwDataSize); 
if(bind(sr,(LPSOCKADDR)&here1,sizeof(here1))) 

MessageBox(hwnd,“接收套接字綁定失敗!”,“”,MB_OK); 
return(FALSE); 

return(TRUE); 

//套接字緩沖區(qū)設(shè)置 
void sockBuffer(void) 

hSendData=GlobalAlloc(GMEM_MOVEABLE|GMEM_SHARE,dwDataSize); 
if(!hSendData) 

MessageBox(hwnd,“發(fā)送套接字緩沖區(qū)定位失敗!”,NULL, 
MB_OK|MB_ICONEXCLAMATION); 
return; 

if((sockBufferS=GlobalLock(hSendData)==NULL) 

MessageBox(hwnd,“發(fā)送套接字緩沖區(qū)鎖定失敗!”,NULL, 
MB_OK|MB_ICONEXCLAMATION); 
GlobalFree(hRecordData[0]; 
return; 

hReceiveData=globalAlloc(GMEM_MOVEABLE|GMEM_SHARE,dwDataSize); 
if(!hReceiveData) 

MessageBox(hwnd,"“接收套接字緩沖區(qū)定位敗!”,NULL 
MB_OK|MB_ICONEXCLAMATION); 
return; 

if((sockBufferT=Globallock(hReceiveData))=NULL) 
MessageBox(hwnd,"發(fā)送套接字緩沖區(qū)鎖定失敗!”,NULL, 
MB_OK|MB_ICONEXCLAMATION); 
GlobalFree(hRecordData[0]); 
return; 


3.數(shù)據(jù)發(fā)送與接收函數(shù); 

int sendto(SOCKET s.char*buf,int len,int flags,struct sockaddr_in to,int 
tolen); 
int recvfrom(SOCKET s.char*buf,int len,int flags,struct sockaddr_in 
fron,int*fromlen) 
其中,參數(shù)flags一般取0。 

recvfrom()函數(shù)實(shí)際上是讀取sendto()函數(shù)發(fā)過來的一個(gè)數(shù)據(jù)包,當(dāng)讀到的數(shù)據(jù)字節(jié)少于規(guī)定接收的數(shù)目時(shí),就把數(shù)據(jù)全部接收,并返回實(shí)際接收到的字節(jié)數(shù);當(dāng)讀到的數(shù)據(jù)多于規(guī)定值時(shí),在數(shù)據(jù)報(bào)文方式下,多余的數(shù)據(jù)將被丟棄。而在流方式下,剩余的數(shù)據(jù)由下recvfrom()讀出。為了發(fā)送和接收數(shù)據(jù),必須建立數(shù)據(jù)發(fā)送緩沖區(qū)和數(shù)據(jù)接收緩沖區(qū)。規(guī)定:IP層的一個(gè)數(shù)據(jù)報(bào)最大不超過64K(含數(shù)據(jù)報(bào)頭)。當(dāng)緩沖區(qū)設(shè)置得過多、過大時(shí),常因內(nèi)存不夠而導(dǎo)致套接字建立失敗。在減小緩沖區(qū)后,該錯(cuò)誤消失。經(jīng)過實(shí)驗(yàn),文中選用了4K字節(jié)。 

此外,還應(yīng)注意這兩個(gè)函數(shù)中最后參數(shù)的寫法,給sendto()的最后參數(shù)是一個(gè)整數(shù)值,而recvfrom()的則是指向一整數(shù)值的指針。

4.套接字關(guān)閉函數(shù):closesocket(SOCKET s) 

通訊結(jié)束時(shí),應(yīng)關(guān)閉指定的套接字,以釋與之相關(guān)的資源。 

在關(guān)閉套接字時(shí),應(yīng)先對(duì)鎖定的各種緩沖區(qū)加以釋放。其程序片斷為: 

void CloseSocket(void) 

GlobalUnlock(hSendData); 
GlobalFree(hSenddata); 
GlobalUnlock(hReceiveData); 
GlobalFree(hReceiveDava); 
if(WSAAysncSelect(ss,hwnd,0,0)=SOCKET_ERROR) 

MessageBos(hwnd,“發(fā)送套接字關(guān)閉失敗!”,“”,MB_OK); 
return; 

if(WSAAysncSelect(sr,hwnd,0,0)==SOCKET_ERROR) 

MessageBox(hwnd,“接收套接字關(guān)閉失敗!”,“”,MB_OK); 
return; 

WSACleanup(); 
closesockent(ss); 
closesockent(sr); 
return; 

三、Winsock的編程特點(diǎn)與異步選擇機(jī)制 

1 阻塞及其處理方式 

在網(wǎng)絡(luò)通訊中,由于網(wǎng)絡(luò)擁擠或一次發(fā)送的數(shù)據(jù)量過大等原因,經(jīng)常會(huì)發(fā)生交換的數(shù)據(jù)在短時(shí)間內(nèi)不能傳送完,收發(fā)數(shù)據(jù)的函數(shù)因此不能返回,這種現(xiàn)象叫做阻塞。Winsock對(duì)有可能阻塞的函數(shù)提供了兩種處理方式:阻塞和非阻塞方式。在阻塞方式下,收發(fā)數(shù)據(jù)的函數(shù)在被調(diào)用后一直要到傳送完畢或者出錯(cuò)才能返回。在阻塞期間,被阻的函數(shù)不會(huì)斷調(diào)用系統(tǒng)函數(shù)GetMessage()來保持消息循環(huán)的正常進(jìn)行。對(duì)于非阻塞方式,函數(shù)被調(diào)用后立即返回,當(dāng)傳送完成后由Winsock給程序發(fā)一個(gè)事先約定好的消息。 

在編程時(shí),應(yīng)盡量使用非阻塞方式。因?yàn)樵谧枞绞较?,用戶可能?huì)長(zhǎng)時(shí)間的等待過程中試圖關(guān)閉程序,因?yàn)橄⒀h(huán)還在起作用,所以程序的窗口可能被關(guān)閉,這樣當(dāng)函數(shù)從Winsock的動(dòng)態(tài)連接庫(kù)中返回時(shí),主程序已經(jīng)從內(nèi)存中刪除,這顯然是極其危險(xiǎn)的。 

2 異步選擇函數(shù)WSAAsyncSelect()的使用 

Winsock通過WSAAsyncSelect()自動(dòng)地設(shè)置套接字處于非阻塞方式。使用WindowsSockets實(shí)現(xiàn)Windows網(wǎng)絡(luò)程序設(shè)計(jì)的關(guān)鍵就是它提供了對(duì)網(wǎng)絡(luò)事件基于消息的異步存取,用于注冊(cè)應(yīng)用程序感興趣的網(wǎng)絡(luò)事件。它請(qǐng)求Windows Sockets DLL在檢測(cè)到套接字上發(fā)生的網(wǎng)絡(luò)事件時(shí),向窗口發(fā)送一個(gè)消息。對(duì)UDP協(xié)議,這些網(wǎng)絡(luò)事件主要為: 

FD_READ 期望在套接字收到數(shù)據(jù)(即讀準(zhǔn)備好)時(shí)接收通知; 

FD_WRITE 期望在套接字可發(fā)送數(shù)(即寫準(zhǔn)備好)時(shí)接收通知; 

FD_CLOSE 期望在套接字關(guān)閉時(shí)接電通知 

消息變量wParam指示發(fā)生網(wǎng)絡(luò)事件的套接字,變量1Param的低字節(jié)描述發(fā)生的網(wǎng)絡(luò)事件,高字包含錯(cuò)誤碼。如在窗口函數(shù)的消息循環(huán)中均加一個(gè)分支: 

int ok=sizeof(SOCKADDR); 
case wMsg; 
switch(1Param) 

case FD_READ: 
//套接字上讀數(shù)據(jù) 
if(recvfrom(sr.lpPlayData[j],dwDataSize,0,(struct sockaddr FAR*)&there1, 

(int FAR*)&ok)==SOCKET_ERROR0 

MessageBox)hwnd,“數(shù)據(jù)接收失敗!”,“”,MB_OK); 
return(FALSE); 

case FD_WRITE: 
//套接字上寫數(shù)據(jù) 

break; 
在程序的編制中,應(yīng)根據(jù)需要靈活地將WSAAsyncSelect()函靈敏放在相應(yīng)的消息循環(huán)之中,其它說明可參見文獻(xiàn)[1]。此外,應(yīng)該指出的是,以上程序片斷中的消息框主要是為程序調(diào)試方便而設(shè)置的,而在正式產(chǎn)品中不再出現(xiàn)。同時(shí),按照程序容錯(cuò)誤設(shè)計(jì),應(yīng)建立一個(gè)專門的容錯(cuò)處理函數(shù)。程序中可能出現(xiàn)的各種錯(cuò)誤都將由該函數(shù)進(jìn)行處理,依據(jù)錯(cuò)誤的危害程度不同,建立幾種不同的處理措施。這樣,才能保證雙方通話的順利和可靠。

查看完整回答
反對(duì) 回復(fù) 2023-03-22
  • 1 回答
  • 0 關(guān)注
  • 101 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)