[问题] 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