从UDP套接字(端口7078)读取数据时出现问题。我已经调用了WSARecvMsg函数并收到了WSAEWOULDBLOCK错误。但是,Wireshark在端口7078上捕获传入的UDP数据包!请帮帮我!
这是我创建和绑定套接字
的代码static ortp_socket_t create_and_bind(const char *addr, int *port, int *sock_family, bool_t reuse_addr){
int err;
int optval = 1;
ortp_socket_t sock=-1;
char num[8];
struct addrinfo hints, *res0, *res;
if (*port==-1) *port=0;
if (*port==0) reuse_addr=FALSE;
memset(&hints, 0, sizeof(hints));
hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
snprintf(num, sizeof(num), "%d",*port);
err = getaddrinfo(addr,num, &hints, &res0);
if (err!=0) {
ortp_warning ("Error in getaddrinfo on (addr=%s port=%i): %s", addr, *port, gai_strerror(err));
return -1;
}
for (res = res0; res; res = res->ai_next) {
sock = socket(res->ai_family, res->ai_socktype, 0);
if (sock==-1)
continue;
if (reuse_addr){
err = setsockopt (sock, SOL_SOCKET, SO_REUSEADDR,
(SOCKET_OPTION_VALUE)&optval, sizeof (optval));
if (err < 0)
{
ortp_warning ("Fail to set rtp address reusable: %s.", getSocketError());
}
}
err = 0;
switch (res->ai_family) {
default:
case AF_INET:
break;
case AF_INET6:
break;
}
if (err < 0) {
ortp_warning("Fail to set recv TTL/HL socket option: %s.", getSocketError());
}
*sock_family=res->ai_family;
err = bind (sock, res->ai_addr, res->ai_addrlen);
if (err != 0){
ortp_debug ("Fail to bind rtp socket to (addr=%s port=%i) : %s.", addr, *port, getSocketError());
close_socket (sock);
sock=-1;
continue;
}
switch (res->ai_family)
{
case AF_INET:
if (IN_MULTICAST(ntohl(((struct sockaddr_in *) res->ai_addr)->sin_addr.s_addr)))
{
struct ip_mreq mreq;
mreq.imr_multiaddr.s_addr = ((struct sockaddr_in *) res->ai_addr)->sin_addr.s_addr;
mreq.imr_interface.s_addr = INADDR_ANY;
err = setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (SOCKET_OPTION_VALUE) &mreq, sizeof(mreq));
if (err < 0){
ortp_warning ("Fail to join address group: %s.", getSocketError());
close_socket (sock);
sock=-1;
continue;
}
}
break;
case AF_INET6:
if (IN6_IS_ADDR_MULTICAST(&(((struct sockaddr_in6 *) res->ai_addr)->sin6_addr)))
{
struct ipv6_mreq mreq;
mreq.ipv6mr_multiaddr = ((struct sockaddr_in6 *) res->ai_addr)->sin6_addr;
mreq.ipv6mr_interface = 0;
err = setsockopt(sock, IPPROTO_IPV6, IPV6_JOIN_GROUP, (SOCKET_OPTION_VALUE)&mreq, sizeof(mreq));
if (err < 0)
{
ortp_warning ("Fail to join address group: %s.", getSocketError());
close_socket (sock);
sock=-1;
continue;
}
}
break;
}
break;
}
freeaddrinfo(res0);
#if defined(WIN32) || defined(_WIN32_WCE)
if (ortp_WSARecvMsg == NULL) {
GUID guid = WSAID_WSARECVMSG;
DWORD bytes_returned;
if (WSAIoctl(sock, SIO_GET_EXTENSION_FUNCTION_POINTER, &guid, sizeof(guid),
&ortp_WSARecvMsg, sizeof(ortp_WSARecvMsg), &bytes_returned, NULL, NULL) == SOCKET_ERROR) {
ortp_warning("WSARecvMsg function not found.");
}
}
#endif
if (sock!=-1){
set_non_blocking_socket (sock);
if (*port==0){
struct sockaddr_storage saddr;
socklen_t slen=sizeof(saddr);
err=getsockname(sock,(struct sockaddr*)&saddr,&slen);
if (err==-1){
ortp_error("getsockname(): %s",getSocketError());
close(sock);
return (ortp_socket_t)-1;
}
err=getnameinfo((struct sockaddr*)&saddr, slen, NULL, 0, num, sizeof(num), NI_NUMERICHOST | NI_NUMERICSERV);
if (err!=0){
ortp_error("getnameinfo(): %s",gai_strerror(err));
close(sock);
return (ortp_socket_t)-1;
}
*port=atoi(num);
}
}
return sock;
}
我使用WSAIoctl来获取WSARECVMSG函数指针
typedef INT (WINAPI * LPFN_WSARECVMSG)(SOCKET, LPWSAMSG, LPDWORD, LPWSAOVERLAPPED, LPWSAOVERLAPPED_COMPLETION_ROUTINE);
static LPFN_WSARECVMSG ortp_WSARecvMsg = NULL;
if (ortp_WSARecvMsg == NULL) {
GUID guid = WSAID_WSARECVMSG;
DWORD bytes_returned;
if (WSAIoctl(sock, SIO_GET_EXTENSION_FUNCTION_POINTER, &guid, sizeof(guid),
&ortp_WSARecvMsg, sizeof(ortp_WSARecvMsg), &bytes_returned, NULL, NULL) == SOCKET_ERROR) {
ortp_warning("WSARecvMsg function not found.");
}
}
我接收数据的代码
int rtp_session_rtp_recv_abstract(ortp_socket_t socket, mblk_t *msg, int flags, struct sockaddr *from, socklen_t *fromlen) {
int ret;
int bufsz = (int) (msg->b_datap->db_lim - msg->b_datap->db_base);
char control[512];
WSAMSG msghdr;
WSACMSGHDR *cmsghdr;
WSABUF data_buf;
DWORD bytes_received;
if (ortp_WSARecvMsg == NULL) {
return recvfrom(socket, (char *)msg->b_wptr, bufsz, flags, from, fromlen);
}
memset(&msghdr, 0, sizeof(msghdr));
memset(control, 0, sizeof(control));
if(from != NULL && fromlen != NULL) {
msghdr.name = from;
msghdr.namelen = *fromlen;
}
data_buf.buf = (char *)msg->b_wptr;
data_buf.len = bufsz;
msghdr.lpBuffers = &data_buf;
msghdr.dwBufferCount = 1;
msghdr.Control.buf = control;
msghdr.Control.len = sizeof(control);
msghdr.dwFlags = flags;
ret = ortp_WSARecvMsg(socket, &msghdr, &bytes_received, NULL, NULL);
if(fromlen != NULL)
*fromlen = msghdr.namelen;
if(ret >= 0) {
ret = bytes_received;
}
else
{
int i;
long m_ErrorCode = WSAGetLastError();
i = 0;
}
return ret;
}