udp 网络编程服务端接收到的端口号与客户端中定义的端口号不一样,请高手指教。

hei鹰 2012-12-29 08:51:23
为什么下面的程序在server端接收到的 端口号不是5150,而是2711,(或者其他的端口号,每次运行的结果都不一样)???
通过这句来打印:
printf("We successfully received %d bytes from address %s:%d.\n", Ret,
inet_ntoa(SenderAddr.sin_addr), ntohs(SenderAddr.sin_port));


server端:

#include <winsock2.h>
#include <stdio.h>

void main(void)
{
WSADATA wsaData;
SOCKET ReceivingSocket;
SOCKADDR_IN ReceiverAddr;
int Port = 5150;
char ReceiveBuf[1024];
int BufLength = 1024;
SOCKADDR_IN SenderAddr;
int SenderAddrSize = sizeof(SenderAddr);
int Ret;


// Initialize Winsock version 2.2

if ((Ret = WSAStartup(MAKEWORD(2,2), &wsaData)) != 0)
{
// NOTE: Since Winsock failed to load we cannot use WSAGetLastError
// to determine the error code as is normally done when a Winsock
// API fails. We have to report the return status of the function.

printf("ERROR: WSAStartup failed with error %d\n", Ret);
return;
}


// Create a new socket to receive datagrams on.

if ((ReceivingSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))
== INVALID_SOCKET)
{
printf("ERROR: socket failed with error %d\n", WSAGetLastError());
WSACleanup();
return;
}

// Setup a SOCKADDR_IN structure that will tell bind that we
// want to receive datagrams from all interfaces using port
// 5150.

ReceiverAddr.sin_family = AF_INET;
ReceiverAddr.sin_port = htons(Port);
ReceiverAddr.sin_addr.s_addr = htonl(INADDR_ANY);

// Associate the address information with the socket using bind.

if (bind(ReceivingSocket, (SOCKADDR *)&ReceiverAddr, sizeof(ReceiverAddr))
== SOCKET_ERROR)
{
printf("ERROR: bind failed with error %d\n", WSAGetLastError());
closesocket(ReceivingSocket);
WSACleanup();
return;
}

printf("We are ready to receive 1 datagram from any interface on port %d...\n",
Port);

// At this point you can receive datagrams on your bound socket.

if ((Ret = recvfrom(ReceivingSocket, ReceiveBuf, BufLength, 0,
(SOCKADDR *)&SenderAddr, &SenderAddrSize)) == SOCKET_ERROR)
{
printf("ERROR: recvfrom failed with error %d\n", WSAGetLastError());
closesocket(ReceivingSocket);
WSACleanup();
return;
}

printf("We successfully received %d bytes from address %s:%d.\n", Ret,
inet_ntoa(SenderAddr.sin_addr), ntohs(SenderAddr.sin_port));


// When your application is finished receiving datagrams close
// the socket.

closesocket(ReceivingSocket);

// When your application is finished call WSACleanup.

WSACleanup();
}





client端:
#include <winsock2.h>
#include <stdio.h>

void main(int argc, char **argv)
{
WSADATA wsaData;
SOCKET SendingSocket;
SOCKADDR_IN ReceiverAddr;
int Port = 5150;
int Ret;

/*if (argc <= 1)
{
printf("USAGE: udpsender <receiver IP address>.\n");
return;
}*/

// Initialize Winsock version 2.2

if ((Ret = WSAStartup(MAKEWORD(2,2), &wsaData)) != 0)
{
// NOTE: Since Winsock failed to load we cannot use WSAGetLastError
// to determine the error code as is normally done when a Winsock
// API fails. We have to report the return status of the function.

printf("ERROR: WSAStartup failed with error %d\n", Ret);
return;
}

// Create a new socket to receive datagrams on.

if ((SendingSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))
== INVALID_SOCKET)
{
printf("ERROR: socket failed with error %d\n", WSAGetLastError());
WSACleanup();
return;
}

// Setup a SOCKADDR_IN structure that will identify who we
// will send datagrams to. For demonstration purposes, let's
// assume our receiver's IP address is 136.149.3.29 and waits
// for datagrams on port 5150. Obviously you will want to prompt
// the user for an IP address and port number and fill these
// fields in with the data from the user.

ReceiverAddr.sin_family = AF_INET;
ReceiverAddr.sin_port = htons(Port);
//ReceiverAddr.sin_addr.s_addr = inet_addr(argv[1]);
ReceiverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
// Send a datagram to the receiver.

if ((Ret = sendto(SendingSocket, "Hello", 5, 0,
(SOCKADDR *)&ReceiverAddr, sizeof(ReceiverAddr))) == SOCKET_ERROR)
{
printf("ERROR: sendto failed with error %d\n", WSAGetLastError());
closesocket(SendingSocket);
WSACleanup();
return;
}

// When your application is finished sending datagrams close
// the socket.

printf("We successfully sent %d byte(s) to %s:%d.\n", Ret,
inet_ntoa(ReceiverAddr.sin_addr), htons(ReceiverAddr.sin_port));

closesocket(SendingSocket);

// When your application is finished call WSACleanup.

WSACleanup();
}
...全文
731 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
Volatile_xian 2013-10-09
  • 打赏
  • 举报
回复
讲得真好
hanyue03 2012-12-31
  • 打赏
  • 举报
回复
引用 3 楼 cqtddt 的回复:
其实你就没理解服务端和客户端的连接 服务端的5150是说程序和计算机的5150端口绑定,所有到计算机5150的数据包,都会发到服务端 客户端的5150是说你要连接到服务端的5150端口.而不是说客户端必须从5150端口去连接服务器,其实你理解的前提是服务端和客户端是在两台不同的计算机上. 这样两者才能建立一条链接.
正解
撑起头顶的天 2012-12-30
  • 打赏
  • 举报
回复
其实你就没理解服务端和客户端的连接 服务端的5150是说程序和计算机的5150端口绑定,所有到计算机5150的数据包,都会发到服务端 客户端的5150是说你要连接到服务端的5150端口.而不是说客户端必须从5150端口去连接服务器,其实你理解的前提是服务端和客户端是在两台不同的计算机上. 这样两者才能建立一条链接.
以免我忘记 2012-12-30
  • 打赏
  • 举报
回复
楼上正解。就是这样的。
evahelen_study 2012-12-29
  • 打赏
  • 举报
回复
因为你的客户端没有调用bind,所以sendto时,系统选择一个临时端口,结果每次都不同,你可以看下《WinSock网络编程经络》,有介绍,这有很多socket例子: http://download.csdn.net/detail/geoff08zhang/4571358

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧