WinSock bind Error 10014错误,怎么解决呢,在线等

尘墨mxy 2013-08-25 09:08:54
代码贴出来

// T2Server.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

#include<iostream>

#include<WinSock2.h>

#pragma comment(lib,"WS2_32")

using namespace std;

#define REQUEST_BACKLOG 5


//如果想要使用SOCKET,WSAStartup函数必须要进行初始化才可以
bool initWSA(const WORD &wVersion ,WSADATA *wsadata)
{
int Ret = 0;
if(Ret = WSAStartup(wVersion,wsadata)!=0)
{
cout<<"WSAStartup Error "<<Ret<<endl;

return FALSE;
}
return true;
}


void cleanWSA()
{
if(WSACleanup() == SOCKET_ERROR)
{
cout<<"WSACleanup failed ,error"<<WSAGetLastError()<<endl;

}
}

//这个是初始化服务器地址,包括IP地址和端口
void InitSockAddrByIP(SOCKADDR_IN *pSockAddr ,const char FAR*strIP,const INT &nPortID)
{
pSockAddr->sin_family = AF_INET;

//htons这个不能忘了,网络字节序必须要转换,不然经常会出大问题
pSockAddr->sin_port = htons(nPortID);

if(0!=strlen(strIP))
{
pSockAddr->sin_addr.s_addr = inet_addr(strIP);
}
else
{

pSockAddr->sin_addr.s_addr =htonl(INADDR_ANY);
}
}


//将端口地址对象和sock对象进行绑定,也就是和后文的sock_listen对象
bool bindAddr(const SOCKADDR_IN * pSockAddr ,SOCKET pSocket)
{
int bindResult = bind(pSocket,(sockaddr*)(pSockAddr),sizeof(pSockAddr));

if(SOCKET_ERROR == bindResult)
{
cout<<"bind error : "<<WSAGetLastError()<<endl;
return false;
}
else
return true;
}

//这个是创建监听器,一旦有连接请求和发送信息的请求我们就能接收到了
bool SetListen(SOCKET s,int backlog)
{
int ListenResult = listen(s,backlog);

if(SOCKET_ERROR == ListenResult)
{
cout<<"listen error"<<WSAGetLastError()<<endl;
return false;
}
else
return true;
}


int _tmain(int argc, char* argv[])
{
WSADATA wsadata;
if(!initWSA(MAKEWORD(2,2),&wsadata))
{
return 0;
}


//指定连接IP地址和服务器端口
SOCKADDR_IN internetAddr;
char FAR *strIP ="121.181.53.81";//这个是服务器的IP地址
INT nPortID = 5150;
InitSockAddrByIP(&internetAddr,strIP,nPortID);

//创建listener_socket
SOCKET listener_socket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(INVALID_SOCKET ==listener_socket)
{
cout<<"listener_socket creat failed"<<endl;
return 0;
}

if(!bindAddr(&internetAddr,listener_socket))
return 0;



if (!SetListen(listener_socket, REQUEST_BACKLOG ) )

{
return 0;

}

cout<<"server started ~~~"<<endl;


//创建socket保存结构
fd_set fdSocket;
FD_ZERO(&fdSocket);
FD_SET(listener_socket,&fdSocket);


//查找可读的socket
while(1)
{

//这个只是一个缓冲对象
fd_set fdSocket_temp;
fdSocket_temp = fdSocket;

//这个是读用的
fd_set fdRead;
fdRead = fdSocket;

//这个是catch错误用的
fd_set fdExceptds;
fdExceptds = fdSocket;

//除了第一个参数,第二个参数是读fd_set对象,第三个参数是写fd_set对象,第四个参数是catch错误的fd_set对象
int nResult_select = select(0,&fdRead,NULL,&fdExceptds,NULL);

//这个时候表示有消息了
if(0 <nResult_select)
{
int socket_count = fdSocket_temp.fd_count;

for(int i =0;i<socket_count;i++)
{
//如果现在fdRead里有消息传来
if(FD_ISSET(fdSocket_temp.fd_array[i],&fdRead))
{
if(fdSocket_temp.fd_array[i]==listener_socket)
//如果是当前正在监听的表示这个还未接受连接,那我们就接下来连接就好了,其他的已经连接上的就接收信息就好了
{
if(fdSocket.fd_count<FD_SETSIZE)
{
//接受这个新的连接
SOCKADDR_IN ClientAddr;
int addrlen = static_cast<int>(sizeof(ClientAddr)); //一定要赋值

SOCKET newClient_SOCKET = accept(listener_socket,(sockaddr *)&ClientAddr,&addrlen);
if(INVALID_SOCKET==newClient_SOCKET)
{
cout<<"accep error "<<WSAGetLastError()<<endl;
}
else
{
FD_SET(newClient_SOCKET,&fdSocket);
cout<<"add new connect"<<endl;
}

}
else
{
cout<<"too much connecttion"<<endl;
}
}
//已经连接上了的我们就直接接收数据好了
else
{
char recvbuff[1024];
int ret = 0;

ret = recv(fdSocket_temp.fd_array[i],recvbuff,static_cast<int>(strlen(recvbuff)),0);
if(ret>0)
{
recvbuff[ret]='\0';
cout<<"recv: "<<recvbuff<<endl;

//回复给客户端
char backbuf[1024]="recevie OK";
send( fdSocket_temp.fd_array[i], backbuf, static_cast<int>( strlen(backbuf) ), 0 );
}

else
{
//连接已经断开了。断开有很短原因
closesocket(fdSocket_temp.fd_array[i]);
//在fd_set中去掉这个连接
FD_CLR(fdSocket_temp.fd_array[i],&fdSocket );
}

}

}

//既然没有发送消息又占用了连接的位置,我们就释放他来控制空闲的空间
else if(fdSocket_temp.fd_array[i] != listener_socket )
{
//该连接断开

closesocket( fdSocket_temp.fd_array[i] );

FD_CLR( fdSocket_temp.fd_array[i], &fdSocket );


}

//如果Catch到了错误
if(FD_ISSET(fdSocket_temp.fd_array[i],&fdExceptds)&& (fdSocket_temp.fd_array[i] != listener_socket) )

{
//该连接断开

closesocket( fdSocket_temp.fd_array[i] );

FD_CLR( fdSocket_temp.fd_array[i], &fdSocket );


}
}
}

else if( SOCKET_ERROR ==nResult_select )

{

cout << "select error : " << WSAGetLastError() << endl;

return 0;

}

Sleep(50);//这个必须要,不然死循环一直弄下去机子可能会死去。。

}

closesocket(listener_socket);
cleanWSA();

return 0;

}

...全文
862 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
尘墨mxy 2013-08-27
  • 打赏
  • 举报
回复
这个问题我自己查MSDN解决了。主要有两个错误,第一个 bind(pSocket,(sockaddr*)(pSockAddr),sizeof(pSockAddr));这里的sizeof(pSockAddr)改成sizeof(SOCKADDR_IN),查过MSDN,SOCKADDR_IN的大小要比pSockAddr大,第二个错误 pSockAddr->sin_addr.s_addr = inet_addr(strIP);改成 pSockAddr->sin_addr.s_addr =htonl(INADDR_ANY);就好了。貌似是自动绑定IP?
max_min_ 2013-08-25
  • 打赏
  • 举报
回复

//不要这个ip,直接传空值过去试试
// char FAR *strIP ="121.181.53.81";//这个是服务器的IP地址     INT nPortID = 5150;     InitSockAddrByIP( &internetAddr, NULL, nPortID); 
尘墨mxy 2013-08-25
  • 打赏
  • 举报
回复
用网上别人的代码也会bind error,难道是我电脑的原因?
尘墨mxy 2013-08-25
  • 打赏
  • 举报
回复
在线等,求大神。
一、WinSock简介 Socket(套接字)最初是由加利福尼亚大学Berkeley(伯克利)分校为UNIX操作系统开发的网络通信接口,随着UNIX的广泛使用,Socket成为当前最流行的网络通信应用程序接口之一。20世纪90年代初,由Sun Microsystems,JSB,FTP software,Microdyne和Microsoft等几家公司共同定制了一套标准,即Windows Socket规范,简称WinSock。 VB编写网络程序主要有两种方式:1.winsock控件 2.winsockAPI 二、WinSock控件的使用 1.WinSock控件的主要属性 LocalHostName属性 本地机器名 LocalIP属性 本地机器IP地址 LocalPort属性 本地机器通信程序的端口(0<端口<65536) RemoteHost属性 远程机器名 RemotePort属性 远程机器的通信程序端口 Protocol属性 通过Protocol属性可以设置WinSock控件连接远程计算机使用的协议。可选的协议是TCP和UDP对应的VB的常量分别是sckTCPProtocol和sckUDPProtocol,Winsock控件默认协议是TCP。注意:虽然可以在运行时设置协议,但必须在连接未建立或断开连接后。 SocketHandle属性 返回当前socket连接的句柄,这是只读属性。 RemoteHostIP属性 属性返回远程计算机的IP地址。在客户端,当使用了控件的Connect方法后,远程计算机的IP地址就赋给了RemoteHostIP属性,而在服务器端,当ConnectRequest事件后,远程计算机(客户端)的IP地址就赋给了这个属性。如果使用的是UDP协议那么当DataArrival事件后,发送UDP报文的计算机的IP才赋给了这个属性。 ByteReceived属性 返回当前接收缓冲区中的字节数 State属性 返回WinSock控件当前的状态 常数 值 描述 sckClosed 0 缺省值,关闭。 SckOpen 1 打开。 SckListening 2 侦听 sckConnectionPending 3 连接挂起 sckResolvingHost 4 识别主机。 sckHostResolved 5 已识别主机 sckConnecting 6 正在连接。 sckConnected 7 已连接。 sckClosing 8 同级人员正在关闭连接。 sckError 9   错误 2.WinSock主要方法 Listen方法 方法用于服务器程序,等待客户访问。格式:Winsock对象.listen Connect方法 用于向远程主机发出连接请求。格式:Winsock对象.connect [远程主机IP,远程端口] Accept方法 用于接受一个连接请求。格式:Winsock对象.accept Request ID Senddata方法 用于发送数据。格式:Winsock对象.senddata 数据 Getdata方法 用来取得接收到的数据。格式:Winsock对象.getdata 变量 [,数据类型 [,最大长度]] Close方法 关闭当前连接。格式:Winsock对象.close Bind方法 用Bind方法可以把一个端口号固定为本控件使用,使得别的应用程序不能再使用这个端口。 Listen方法Listen方法只在使用TCP协议时有用。它将应用程序置于监听检测状态。 Connect方法 当本地计算机希望和远程计算机建立连接时,就可以调用Connect方法。Connect方法调用的规范为:Connect RemoteHost,RemotePort Accept方法 当服务器接收到客户端的连接请求后,服务器有权决定是否接受客户端的请求。 SendData方法当连接建立后,要发送数据就可以调用SendData方法,该方法只有一个参数,就是要发送的数据。 GetData方法 当本地计算机接收到远程计算机的数据时,数据存放在缓冲区中,要从缓冲区中取出数据,可以使用GetData方法。GetData方法调用规范如下:GetData

3,882

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 其它技术问题
社区管理员
  • 其它技术问题社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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