作者s890269 (赛)
看板C_and_CPP
标题[问题] UDP Server Client
时间Wed Oct 26 14:50:40 2016
大家好,我使用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;
}
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 140.116.234.232
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/C_and_CPP/M.1477464642.A.804.html
※ 编辑: s890269 (140.116.234.232), 10/26/2016 17:00:39
1F:推 hn12404988: 完全可以啊,无法传输是显示出甚麽讯息或状况? 10/26 17:00
※ 编辑: s890269 (140.116.234.232), 10/26/2016 17:01:07
2F:→ hn12404988: Sorry, 手上没有windows系统的电脑,无法run你的code 10/26 17:01
3F:推 hn12404988: 你的define server怎麽会是127.0.0.1 你不是两台了? 10/26 17:05
4F:推 godspeedlee: 这麽长的距离用UDP很冒险喔 10/26 18:01
5F:→ s890269: 抱歉,因为我属於重做学长的实验并修改,但一开始没什麽方, 10/26 18:28
6F:→ s890269: 向,所以绕了远路现在剩没多少时间,如果两台,Server应该要 10/26 18:28
7F:→ s890269: 怎麽填写? 10/26 18:29
8F:→ s890269: 很冒险是因为距离太远容易掉封包?还是应该用TCP? 10/26 18:29
9F:→ s890269: 还是两者都危险?因为用UDP是教授的想法,也是有学长做过的 10/26 18:30
10F:→ s890269: 两台电脑是填另一台电脑的网路IP位置吗? 10/26 18:41
11F:推 Qbsuran: 如果要模拟延迟的话 加个Sleep之类的 10/26 19:12
12F:→ s890269: 谢谢你的建议,但paper的reviewer说要看实际的延迟, 10/26 19:38
13F:→ s890269: 所以目前还没打算用Sleep的方式 10/26 19:38
14F:推 tsoahans: #define SERVER "127.0.0.1"这边改开server那台电脑的IP 10/26 21:26
15F:推 noodleT: client 的 char buf[255]; 有问题 10/26 22:03
16F:推 noodleT: UDP 传讯息是属於自言自语,不管对方在不在线上,也不做 10/26 22:09
17F:→ noodleT: 封包确认。TCP 会做交握、封包确认,确保对方收到的资料 10/26 22:09
18F:→ noodleT: 是正确的。因此TCP 一般比 UDP 耗时 10/26 22:09
19F:推 CodingMan: 一台 vpn到美国去? 10/26 22:11
20F:推 noodleT: 你要看你的应用是属於那一种,跟教授讨论确认後再动工。 10/26 22:13
21F:→ noodleT: 不然做白工反而拖累论文时间 10/26 22:13
22F:推 noodleT: TCP也是会掉封包的,但他有机制可以重传。server不需要事 10/26 22:24
23F:→ noodleT: 先知道client的IP,server要负责开一个监听器等待用户连 10/26 22:24
24F:→ noodleT: 线。连线事件触发後自然会知道是哪个用户要求连线,因此 10/26 22:24
25F:→ noodleT: 事先不需知道对方IP 10/26 22:25
26F:→ pttworld: client要知道server IP,server自己可以是localhost。 10/26 23:13
27F:→ pttworld: 测程式之前先使用既有软体测两台通畅过防火墙规则。 10/26 23:14
28F:→ pttworld: 远端测试请找大学同学读别间研所的或不同实验室同梯。 10/26 23:15
29F:→ y3k: UDP原生应该没啥Server Client的概念吧XD 10/27 00:44
30F:→ shaopin: 使用AWS EC2 或是Google GCE 就可以不求人 10/27 13:22
31F:→ shaopin: UDP 还是有server client 10/27 13:31
32F:→ s890269: 我大致了解了,我用实验室电脑跟家里电脑测试 10/27 17:32
33F:→ s890269: 并且Client IP位置有更改,Client有显示讯息传出去 10/27 17:33
34F:→ s890269: 但server那里好像没有收到,是指这样就代表遗失了吗...? 10/27 17:33
35F:→ s890269: 两者距离骑车五分钟而已,还是封包遗失有其他因素存在? 10/27 17:34
36F:→ s890269: 我把两台的防火墙都关掉了,Server还是没收到 10/27 17:47
37F:推 noodleT: 你可以试试看能不能ping到server 10/27 18:04
38F:→ s890269: 出现要求等候逾时,所以是没ping到的意思吗? 10/27 20:13
39F:推 noodleT: 对,还有一个问题是你实验室的电脑是连到学校的伺服器, 10/27 20:47
40F:→ noodleT: 电脑上的IP是学校发的虚拟IP。这个IP并不真的在internet 10/27 20:47
41F:→ noodleT: 中。所以像租屋处的电脑是ping不到学校电脑的。 10/27 20:47
42F:→ noodleT: 要测试你的UDP程式最简单的方法是拿网路线直接连接两台电 10/27 20:48
43F:→ noodleT: 脑 10/27 20:48
44F:→ noodleT: 然後网路稳不稳跟现实距离大小我想是没有绝对的关系。 10/27 20:50
45F:→ s890269: 是因为虚拟IP:192.168.XX.XX这个原因吗? 10/27 20:57
46F:→ s890269: 但不论我手机热点或者租处都是192.168开头 10/27 20:57
47F:→ s890269: 所以可能无法准确的测试?还是和192.168.XX.XX无关 10/27 20:58
48F:推 noodleT: 实验室电脑的IP比较重要 10/27 21:03
49F:→ s890269: 我用实验室的两台电脑是测试可以的了 10/27 21:05
50F:→ s890269: 所以是因为在同一个区网里所以可以? 10/27 21:06
51F:→ s890269: 我用租屋处,192.168.XX.XX和实验室的测试就无法 10/27 21:06
52F:→ s890269: n大好厉害呀,如果我要实际测试,还是要脱离区网才行? 10/27 21:08
53F:推 noodleT: 但生实体IP比较难,不如用实验室+图书馆电脑做测试 10/27 21:17
54F:→ s890269: 但我租屋处跟实验室测试应该跟图书馆测试是一样的吧? 10/27 21:20
55F:→ s890269: 所以实际上还有一些问题?但我不知道那是不是程式码的问题 10/27 21:21
56F:→ s890269: 因为租屋处跟实验室是无法传递的 10/27 21:21
57F:推 noodleT: 图书馆电脑有机会跟实验室电脑在同一个网域底下,因为你 10/27 21:43
58F:→ noodleT: 说实验室两台电脑测试ok,所以只是提供你较长距离的测试 10/27 21:43
59F:→ noodleT: 方法 10/27 21:43
60F:→ noodleT: client. server两端都在校内的话,应该都能成功 10/27 21:45
61F:推 firejox: 无法直接传递主要是中间有个NAT的关系 10/27 21:51
62F:→ s890269: 所以如果我想要两台电脑连线,又不在区网的话 10/29 01:45
63F:→ s890269: 一定要实体IP是吗?192.168这种虚拟IP没在区网里的话, 10/29 01:46
64F:→ s890269: 是没办法互相连线的? 10/29 01:46
65F:→ LPH66: 是的, 这也正是那些虚拟私人区网服务(如Hamachi)在解决的事 10/29 05:19
67F:推 noodleT: client端应该可以是虚拟IP 10/29 06:45
68F:→ s890269: 我本来想用hamachi让我家跟我外宿的地方变一个区网 10/29 11:58
69F:→ s890269: 但这样的连线好像也是失败了,还是这样是有机会可以成功 10/29 11:59
70F:→ s890269: 突然发现我用hamachi设定成功了,谢谢上面回答我的各位 10/29 12:15
71F:→ s890269: 如果真的有问题我再上来发问,真的麻烦大家了 10/29 12:15
72F:→ s890269: 使用hamachi让我家跟外宿区用UDP连线成功 10/29 12:19
73F:→ s890269: 对了我想问一下,UDP传送封包给Server,如果Server没收到 10/29 16:41
74F:→ s890269: 是封包就遗失了吗?还是会一直塞住,但Client继续送? 10/29 16:42
75F:推 noodleT: UDP 传过就算了,不会确认 10/29 17:59
76F:推 LucasChen: udp = 射後不理 11/04 17:03