我現在需要從內網的一臺電腦上向外網的服務器發送一個資料,然后接收服務器回傳來的資訊。
我的步驟是這樣的:
1、創建一個發送套接字mSckSender,將mSckSender系結到自己電腦的內網IP 192.168.1.173 和埠 3000上。
2、創建一個接收套接字mSckReceiver,將mSckReceiver系結到本地埠 3000上。
3、開啟一個接收執行緒,執行緒中使用mSckReceiver接收資料。
4、然后再在主執行緒中通過mSckSender向服務器發送資料。
不過我一直未收到服務器回傳來的資料,執行緒中一直等待。用測驗工具可以測到服務器是有資料回傳的。
這個是mSckSender的代碼
BOOL CTestDlg::CreateSender(void)
{
//DeleteSender();
mSckSender = socket(AF_INET, SOCK_DGRAM, 0);
if (mSckSender != INVALID_SOCKET)
{
BOOL flag = TRUE;
int retr = setsockopt(mSckSender, SOL_SOCKET, SO_REUSEADDR,
(char *) &flag, sizeof(flag));//設定socket為地址復用
if (retr == SOCKET_ERROR)
{
DeleteReceiver();
return FALSE;
}
int ret = 0;
sockaddr_in addr;
memset((char *) &addr, 0, sizeof(addr));
char ip[20];
char name[20];
GetHostInfo(ip,name);//獲取本機的IP和用戶名
addr.sin_addr.S_un.S_addr = inet_addr(ip);
addr.sin_family = AF_INET;
addr.sin_port = htons(3000);//本機埠,注意該埠一定要和監聽的埠是同一埠(接聽下面會寫)
ret = bind(mSckSender, (struct sockaddr*) &addr, sizeof(addr));//系結要發送的socket
if (ret == SOCKET_ERROR)
{
DeleteSender();
return FALSE;
}
return TRUE;
}
return FALSE;
}
這個是mSckReceiver的代碼
BOOL CTestDlg::CreateReceiver(void)
{
DeleteReceiver();
// 創建一個UDP傳輸的Socket
mSckReceiver = socket(AF_INET, SOCK_DGRAM, 0);
if (mSckReceiver != INVALID_SOCKET)
{
// 在Socket上設定引數:允許地址復用
BOOL flag = TRUE;
int ret = setsockopt(mSckReceiver, SOL_SOCKET, SO_REUSEADDR,
(char *) &flag, sizeof(flag));
if (ret == SOCKET_ERROR)
{
DeleteReceiver();
return FALSE;
}
// 將Socket系結到本地埠號上
SOCKADDR_IN addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(3000);//一定要把這里的監聽埠和發送的設定為同一個埠
ret = bind(mSckReceiver, (struct sockaddr*) &addr, sizeof(addr));
if (ret == SOCKET_ERROR)
{
DeleteReceiver();
return FALSE;
}
return TRUE;
}
return FALSE;
}
這個是發送資料
void CTestDlg::SendData(char* pchar,long length)
{
char* tt = new char[length + 1];
memset(tt,'/0',length + 1);
memcpy(tt,pchar,length);
sockaddr_in remote;
memset((char *) &remote, 0, sizeof(remote));
remote.sin_addr.S_un.S_addr = inet_addr("210.45.212.119");//要發送的服務器IP
remote.sin_family = AF_INET;
remote.sin_port = htons(7002);//服務器的埠
sendto(mSckSender, tt, length, 0, (sockaddr *) &remote, sizeof(remote));
DeleteSender();
delete[] tt;
}
這個是接收資料
void CTestDlg::ReceivingLoop(void)
{
struct sockaddr_in addr_cli;
int addr_cli_len = sizeof(addr_cli);
char buffer[MAX_PATH] = {'/0'};
long bytes = 0;
mIsReceiving = TRUE;
CString tnote = L"";
// 等待接收資料
while (mIsReceiving)
{
int addr_cli_len = sizeof(addr_cli);
bytes = recvfrom(mSckReceiver, (char *)buffer, MAX_PATH,0, (LPSOCKADDR) &addr_cli, (int *) &addr_cli_len);
if (bytes == SOCKET_ERROR || bytes == 0)
{
// 如果Socket發送錯誤或者Socket斷開,則跳出回圈
mIsReceiving = FALSE;
}
else
{
}
}
}
請教一下大家,問題出在哪里,為什么我收不到服務器的資料?
uj5u.com熱心網友回復:
額,沒大神嗎?
uj5u.com熱心網友回復:
求大神指點,在線等
uj5u.com熱心網友回復:
頂一發
uj5u.com熱心網友回復:
remote.sin_port = htons(7002);//服務器的埠,你的服務器系結在3000,你往7002發個毛。收到才怪。uj5u.com熱心網友回復:
bool is_LAN_ok = (boo)(局域網測驗ok嗎?);
if (is_LAN_ok)
{
bool is_NAT_ok = (bool)(內網的埠映射了嗎?)
if (is_NAT_ok)
{
//一般不會執行到這步.
}
else
{
//埠映射,打洞,p2p,upd打洞,tcp通訊,dmz,upnp
}
}
else
{
//測驗程式
}
uj5u.com熱心網友回復:
為什么要一個埠系結多個socket,一個socket就能完成收發,很有可能服務器的資料在另外一個socket緩沖區中的uj5u.com熱心網友回復:
這個3000埠是我本地系結用來接收服務器回傳的資料,而這個7002埠是服務器的埠。你理解錯了。
uj5u.com熱心網友回復:
我將自己本地的發送套接字和接收套接字系結為一個埠,這樣我才能收到外網的服務器向我發送的UDP資訊包啊
uj5u.com熱心網友回復:
一個socket就能完成收和發uj5u.com熱心網友回復:
char* tt = new char[length + 1];memset(tt,'/0',length + 1);
memcpy(tt,pchar,length);
sockaddr_in remote;
memset((char *) &remote, 0, sizeof(remote));
remote.sin_addr.S_un.S_addr = inet_addr("210.45.212.119");//要發送的服務器IP
remote.sin_family = AF_INET;
remote.sin_port = htons(7002);//服務器的埠
sendto(mSckSender, tt, length, 0, (sockaddr *) &remote, sizeof(remote));//我只看到,你是往7002在發
uj5u.com熱心網友回復:
正好是我的問題!轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/145353.html
標籤:網絡通信
上一篇:keytool 錯誤: java.io.FileNotFoundException: cacerts (拒絕訪問。)
