[問題] UDP Server Client

作者: s890269 (賽)   2016-10-26 14:50:40
大家好,我使用Win7以及Microsoft Visual Studio 2010
正在進行UDP相關的實驗
我寫了兩個C++程式碼
一個是Server,一個是Client
但我不確定可不可以這樣做,所以想來問一下
我寫好了兩個程式碼,並且在同一台電腦裡面執行
是可以的,程式碼當中也有顯示連線的Client
我想問的是,我有辦法在一台電腦開啟Server的程式碼,另一台電腦開啟Client的程式碼,
然後進行封包傳輸嗎?
實驗需要相隔兩地,兩地可能是台北跟台南或者甚至到美國
實驗當中需要測試真實的網路延遲,我想使用封包傳過去跟接收回來的時間
有人願意提供我美國主機進行測試
但我自己在實驗室中,利用兩台電腦,一台開起Server另一台開起Client,卻無法進行傳輸
所以想請問一下是本來就無法這樣在兩台電腦各開一個程式碼然後分開進行嗎?
在此附上程式碼:
UDP Server:
///server////
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include<winsock2.h>
#include <iostream>
#include <sys/types.h>
using namespace std;
#pragma comment(lib,"ws2_32.lib") //Winsock Library
#define SERVER_PORT 8888
#define BUFLEN 512
int _tmain(int argc, _TCHAR* argv[]){
struct sockaddr_in addr; /* address of this service *///for one port
SOCKET s;
int length_addr;
char buf[BUFLEN];
int sendbol;
int receivebol;
///一些初始設定/////
WSADATA wsa;
printf("\nInitializing Winsock...");
if (WSAStartup(MAKEWORD(2,2),&wsa) != 0){
printf("Failed. Error Code : %d",WSAGetLastError());
exit(EXIT_FAILURE);
}
printf("Initialized.\n");
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) <0){
perror ("socket failed");
exit(EXIT_FAILURE);
}
memset(&addr,'\0',sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(SERVER_PORT);
if (bind(s,(struct sockaddr*)&addr,sizeof(addr)) <0) {
perror ("bind failed\n");
exit(1);
}
length_addr=sizeof(addr);
printf("Server is ready to receive !!\n");
printf("Can strike Cntrl-c to stop Server >>\n");
memset(buf,'\0', BUFLEN);
////開始接收///////
while(1){
receivebol=recvfrom(s,buf,BUFLEN,0,(struct sockaddr*)&addr,
&length_addr);(跟上一行是同一行)
if (receivebol<0){
perror ("could not read datagram!!");
continue;
}
printf("Received data form %s:%d\n",inet_ntoa(addr.sin_addr),
htons(addr.sin_port));(跟上一行是同一行)
printf("%s\n",buf);
sendbol=sendto(s,buf,BUFLEN,0, (struct sockaddr*)&addr,length_addr);
if (sendbol<0){
perror("Could not send datagram!!\n");
continue;
}
printf("Can Strike Crtl-c to stop Server >>\n");
}
closesocket(s);
WSACleanup();
system("pause");
return 0;
}
UDP Client:
///client/////
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include<winsock2.h>
#include <fcntl.h>
#include <string.h>
#include <iostream>
#pragma comment(lib,"ws2_32.lib")
using namespace std;
#define SERV_PORT 8888 //send to server
#define BUFLEN 512
#define SERVER "127.0.0.1"
int main(int argc, char **argv){
struct sockaddr_in server;//one port
struct hostent *hp; /* holds IP address of server */
SOCKET s;
int size_server;
char data;
char buf[255];
int sendbol, receivebol;
WSADATA wsa;
//一些初始設定///
printf("\nInitializing Winsock...");
if (WSAStartup(MAKEWORD(2,2),&wsa) != 0){
printf("Failed. Error Code : %d",WSAGetLastError());
exit(EXIT_FAILURE);
}
printf("Initialized.\n");
//create socket
if ( (s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == SOCKET_ERROR){
printf("socket() failed with error code : %d" , WSAGetLastError());
exit(EXIT_FAILURE);
}
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl(INADDR_ANY);
server.sin_addr.s_addr=inet_addr(SERVER);
server.sin_port = htons(SERV_PORT);
size_server=sizeof(server);
///////開始發送跟接收///////
while(1){
sprintf(buf,"%f",0.5678);
cout <<buf<< endl;
sendbol=sendto(s,buf,BUFLEN,0,(struct sockaddr*)&server,size_server);
if(sendbol<0) {
perror("sned to server error !");
exit(1);
}
else{
printf("bytes have been sended\n");
}
receivebol=recvfrom(s,buf,BUFLEN,0,(struct sockaddr*)&server,&size_server);
if (receivebol< 0) {
printf("receive failed: %d\n" , WSAGetLastError());
exit (1);
}
else{
printf("bytes have been received\n");
printf("%s\n", buf);
}
}
closesocket(s);
WSACleanup();
system("pause");
return 0;
}
作者: hn12404988 (Willy)   2016-10-26 17:00:00
完全可以啊,無法傳輸是顯示出甚麼訊息或狀況?Sorry, 手上沒有windows系統的電腦,無法run你的code你的define server怎麼會是127.0.0.1 你不是兩台了?
作者: godspeedlee (妳,我可以)   2016-10-26 18:01:00
這麼長的距離用UDP很冒險喔
作者: s890269 (賽)   2016-10-26 18:28:00
抱歉,因為我屬於重做學長的實驗並修改,但一開始沒什麼方,向,所以繞了遠路現在剩沒多少時間,如果兩台,Server應該要怎麼填寫?很冒險是因為距離太遠容易掉封包?還是應該用TCP?還是兩者都危險?因為用UDP是教授的想法,也是有學長做過的兩台電腦是填另一台電腦的網路IP位置嗎?
作者: Qbsuran (Qbsuran)   2016-10-26 19:12:00
如果要模擬延遲的話 加個Sleep之類的
作者: s890269 (賽)   2016-10-26 19:38:00
謝謝你的建議,但paper的reviewer說要看實際的延遲,所以目前還沒打算用Sleep的方式
作者: tsoahans (ㄎㄎ)   2016-10-26 21:26:00
#define SERVER "127.0.0.1"這邊改開server那台電腦的IP
作者: noodleT (麵T)   2016-10-26 22:03:00
client 的 char buf[255]; 有問題UDP 傳訊息是屬於自言自語,不管對方在不在線上,也不做封包確認。TCP 會做交握、封包確認,確保對方收到的資料是正確的。因此TCP 一般比 UDP 耗時
作者: CodingMan (程式俠)   2016-10-26 22:11:00
一台 vpn到美國去?
作者: noodleT (麵T)   2016-10-26 22:13:00
你要看你的應用是屬於那一種,跟教授討論確認後再動工。不然做白工反而拖累論文時間TCP也是會掉封包的,但他有機制可以重傳。server不需要事先知道client的IP,server要負責開一個監聽器等待用戶連線。連線事件觸發後自然會知道是哪個用戶要求連線,因此事先不需知道對方IP
作者: pttworld (批踢踢世界)   2016-10-26 23:13:00
client要知道server IP,server自己可以是localhost。測程式之前先使用既有軟體測兩台通暢過防火牆規則。遠端測試請找大學同學讀別間研所的或不同實驗室同梯。
作者: y3k (激流を制するは静水)   2016-10-27 00:44:00
UDP原生應該沒啥Server Client的概念吧XD
作者: shaopin (Brian)   2016-10-27 13:22:00
使用AWS EC2 或是Google GCE 就可以不求人UDP 還是有server client
作者: s890269 (賽)   2016-10-27 17:32:00
我大致了解了,我用實驗室電腦跟家裡電腦測試並且Client IP位置有更改,Client有顯示訊息傳出去但server那裏好像沒有收到,是指這樣就代表遺失了嗎...?兩者距離騎車五分鐘而已,還是封包遺失有其他因素存在?我把兩台的防火牆都關掉了,Server還是沒收到
作者: noodleT (麵T)   2016-10-27 18:04:00
你可以試試看能不能ping到server
作者: s890269 (賽)   2016-10-27 20:13:00
出現要求等候逾時,所以是沒ping到的意思嗎?
作者: noodleT (麵T)   2016-10-27 20:47:00
對,還有一個問題是你實驗室的電腦是連到學校的伺服器,電腦上的IP是學校發的虛擬IP。這個IP並不真的在internet中。所以像租屋處的電腦是ping不到學校電腦的。要測試你的UDP程式最簡單的方法是拿網路線直接連接兩台電腦然後網路穩不穩跟現實距離大小我想是沒有絕對的關係。
作者: s890269 (賽)   2016-10-27 20:57:00
是因為虛擬IP:192.168.XX.XX這個原因嗎?但不論我手機熱點或者租處都是192.168開頭所以可能無法準確的測試?還是和192.168.XX.XX無關
作者: noodleT (麵T)   2016-10-27 21:03:00
實驗室電腦的IP比較重要
作者: s890269 (賽)   2016-10-27 21:05:00
我用實驗室的兩台電腦是測試可以的了所以是因為在同一個區網裡所以可以?我用租屋處,192.168.XX.XX和實驗室的測試就無法n大好厲害呀,如果我要實際測試,還是要脫離區網才行?
作者: noodleT (麵T)   2016-10-27 21:17:00
但生實體IP比較難,不如用實驗室+圖書館電腦做測試
作者: s890269 (賽)   2016-10-27 21:20:00
但我租屋處跟實驗室測試應該跟圖書館測試是一樣的吧?所以實際上還有一些問題?但我不知道那是不是程式碼的問題因為租屋處跟實驗室是無法傳遞的
作者: noodleT (麵T)   2016-10-27 21:43:00
圖書館電腦有機會跟實驗室電腦在同一個網域底下,因為你說實驗室兩台電腦測試ok,所以只是提供你較長距離的測試方法client. server兩端都在校內的話,應該都能成功
作者: firejox (Tangent)   2016-10-27 21:51:00
無法直接傳遞主要是中間有個NAT的關係
作者: s890269 (賽)   2016-10-29 01:45:00
所以如果我想要兩台電腦連線,又不在區網的話一定要實體IP是嗎?192.168這種虛擬IP沒在區網裡的話,是沒辦法互相連線的?
作者: LPH66 (-6.2598534e+18f)   2016-10-29 05:19:00
是的, 這也正是那些虛擬私人區網服務(如Hamachi)在解決的事關於 NAT 直接看維基解釋: http://tinyurl.com/kgnuyty
作者: noodleT (麵T)   2016-10-29 06:45:00
client端應該可以是虛擬IP
作者: s890269 (賽)   2016-10-29 11:58:00
我本來想用hamachi讓我家跟我外宿的地方變一個區網但這樣的連線好像也是失敗了,還是這樣是有機會可以成功突然發現我用hamachi設定成功了,謝謝上面回答我的各位如果真的有問題我再上來發問,真的麻煩大家了使用hamachi讓我家跟外宿區用UDP連線成功對了我想問一下,UDP傳送封包給Server,如果Server沒收到是封包就遺失了嗎?還是會一直塞住,但Client繼續送?
作者: noodleT (麵T)   2016-10-29 17:59:00
UDP 傳過就算了,不會確認
作者: LucasChen (sleep)   2016-11-04 17:03:00
udp = 射後不理

Links booklink

Contact Us: admin [ a t ] ucptt.com