如何进行阻塞通讯,我使用的socket!

lifejoy 2003-11-25 06:07:59
如何,我怎么一使用?
...全文
11 点赞 收藏 8
写回复
8 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
lifejoy 2003-12-01
分赃了!
回复
redby 2003-11-26
//////////////////////////////////////////////////////////////////////////////////////////
//****** UDP发送数据 ****** /////////
//#define RECV_IP_ADDR "234.5.6.7" // "192.168.0.199"
//#define DEST_PORT 4567
//#define SOURCE_PORT 0

typedef struct _UDP_SETTING {//UDP方式的SOCKET参数设置
char chrRecvIP[16]; //发送方的UDP采用的IP
int intDestPort; //发送方的UDP采用的端口
int intSourcePort; //默认为O;
} UDP_SETTING;

//UDP变量
extern UDP_SETTING g_udpSeting;
回复
redby 2003-11-26
/////////////////////////////////////////////////////////////////////////////////
//函数名: UDP_CreateSocket
//功能: 初始化SOCKET
//参数: 1)sktRec,用于接受数据的SOCKET
// udpSetting 用于设置SOCKET的参数
/////////////////////////////////////////////////////////////////////////////////
int UDP_CreateSocket(SOCKET &sktRec,UDP_SETTING udpSetting)
{
//char szMessageA[100]; // ASCII string
//TCHAR szMessageW[100]; // Unicode string
TCHAR szError[100]; // Error message string

struct ip_mreq mreq; // Used in adding or dropping
// multicasting addresses
SOCKADDR_IN local_sin; // Local socket's address
// recv_sin; // Holds the source address upon
// recvfrom function returns
WSADATA WSAData; // Contains details of the
// Winsock implementation

// Initialize Winsock.
if (WSAStartup (MAKEWORD(1,1), &WSAData) != 0)
{
wsprintf (szError, TEXT("WSAStartup failed! Error: %d"),
WSAGetLastError ());
AfxMessageBox (szError, MB_OK);
return 1;
}

// Create a datagram socket, Sock.
if ((sktRec = socket (AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET)
{
wsprintf (szError, TEXT("Allocating socket failed! Error: %d"),
WSAGetLastError ());
AfxMessageBox (szError, MB_OK);
return 2;
}

// Fill out the local socket's address information.
local_sin.sin_family = AF_INET;
local_sin.sin_port = htons (udpSetting.intDestPort);
local_sin.sin_addr.s_addr = htonl (INADDR_ANY);

// Associate the local address with Sock.
if (bind (sktRec,
(struct sockaddr FAR *) &local_sin,
sizeof (local_sin)) == SOCKET_ERROR)
{
wsprintf (szError, TEXT("Binding socket failed! Error: %d"),
WSAGetLastError ());
AfxMessageBox (szError, MB_OK);
closesocket (sktRec);
return 3;
}

// Join the multicast group from which to receive datagrams.
mreq.imr_multiaddr.s_addr = inet_addr (udpSetting.chrRecvIP);
mreq.imr_interface.s_addr = INADDR_ANY;

if (setsockopt (sktRec,
IPPROTO_IP,
IP_ADD_MEMBERSHIP,
(char FAR *)&mreq,
sizeof (mreq)) == SOCKET_ERROR)
{
wsprintf (szError, TEXT("setsockopt failed! Error: %d"),
WSAGetLastError ());
AfxMessageBox (szError, MB_OK);
closesocket (sktRec);
return 4;
}
return 0;
}

//关闭SOCKET
void UDP_CloseSocket(SOCKET &sktRec)
{
int intCycle=0;
// Disable sending on Sock before closing it.
while (intCycle<5) {
if(shutdown (sktRec, 0x01)==0){
break;
}
intCycle++;
}

intCycle=0;
// Close Sock.
while (intCycle<5) {
if(closesocket(sktRec)==0){
break;
}
intCycle++;
}

while (intCycle<5) {
if(WSACleanup()==0){
break;
}
intCycle++;
}
}

/////////////////////////////////////////////////////////////////////////////////
//函数名: UDP_ReceiveSocket
//功能: 接收数据
//参数: 1)sktRec,用于接受数据的SOCKET
// 2)intFlag 接收方式 0,表示阻塞接收,否则,为非阻塞接收
// 3) bytMsg 存放接收数据的缓冲区
// 4) intLen 接收数据的缓冲区的长度(即要接收的数据长度)
/////////////////////////////////////////////////////////////////////////////////

int UDP_ReceiveSocket(SOCKET &sktRec,int intFlag,BYTE*bytMsg,int intLen)//接收数据
{
int index = 0; // Integer index

SOCKADDR_IN recv_sin;
int iRecvLen; // Length of recv_sin
//char szMessageA[100]; // ASCII string
//TCHAR szMessageW[100]; // Unicode string

//BYTE bytSend[8192]; //接收缓冲取

TCHAR szError[100]; // Error message string

iRecvLen = sizeof (recv_sin);

// Receive data from the multicasting group server.
if (recvfrom (sktRec, (char*)bytMsg,intLen,intFlag,(struct sockaddr FAR *) &recv_sin,&iRecvLen) == SOCKET_ERROR)
{
wsprintf (szError, TEXT("recvfrom failed! Error: %d"),WSAGetLastError());
AfxMessageBox (szError, MB_OK);
closesocket (sktRec);
return 1;
}
return 0;

}
回复
redby 2003-11-26
下面是我封装的几个方法:(UDP)

回复
huanyun 2003-11-25
一个阻塞的线程读取函数

UINT CTelnetCtrl::SocketThread(LPVOID pParam)
{
CTelnetCtrl *pTelnetCtrl = (CTelnetCtrl*)pParam;
pTelnetCtrl->m_bThreadAlive = TRUE;
memset(pTelnetCtrl->m_pReadBuffer, 0, MAX_TELREAD_SIZE);
while(1)
{
DWORD m_Flag=WSAWaitForMultipleEvents(2,pTelnetCtrl->m_hEventArray,false,-1,false);
switch(m_Flag)
{
case WSA_WAIT_EVENT_0://退出
pTelnetCtrl->m_bThreadAlive = FALSE;
AfxEndThread(100);
break;
case WSA_WAIT_EVENT_0+1://Socket消息
{
WSANETWORKEVENTS we;
int iRet=WSAEnumNetworkEvents(pTelnetCtrl->m_Socket,pTelnetCtrl->m_hSocketEvent,&we);
if(we.lNetworkEvents&FD_READ)
{//读取
pTelnetCtrl->RecvTransData();
// printf("FD_READ\n");
}
if(we.lNetworkEvents&FD_ACCEPT)
{
//printf("accept\n");
//OnAccept();
}
if(we.lNetworkEvents&FD_CLOSE)
{
//printf("Close\n");
//pTelnetCtrl->DisConnect();
pTelnetCtrl->Close();
pTelnetCtrl->m_bThreadAlive = FALSE;
AfxEndThread(100);
}
if(we.lNetworkEvents&FD_CONNECT)
{
//printf("accept\n");
//OnConnect();
}
}//end case wsa_wait_event_0
break;
case WSA_WAIT_TIMEOUT: //do timeout
// printf("timeout\n");
break;
case WAIT_IO_COMPLETION:// One or more I/O completion routines are queued for execution.
//printf("One or more I/O completion routines are queued for execution. \n");
break;
case WSANOTINITIALISED:// A successful WSAStartup call must occur before using this function.
//printf("A successful WSAStartup call must occur before using this function. \n");
break;
case WSAENETDOWN:// The network subsystem has failed.
//printf("The network subsystem has failed. \n");
break;
case WSAEINPROGRESS:// A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
//printf("A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function. \n");
break;
case WSA_NOT_ENOUGH_MEMORY: //Not enough free memory available to complete the operation.
//printf("Not enough free memory available to complete the operation. \n");
break;
case WSA_INVALID_HANDLE: //One or more of the values in the lphEvents array is not a valid event object handle.
//printf("One or more of the values in the lphEvents array is not a valid event object handle. \n");
break;
case WSA_INVALID_PARAMETER:// The cEvents parameter does not contain a valid handle count.
//printf("The cEvents parameter does not contain a valid handle count. \n");
break;
default:
break;

}//end switchs
}
return 0;
}
回复
xiaohyy 2003-11-25
默认就是阻塞。。
回复
broadoceans 2003-11-25
你说的是什么阻塞?
回复
sharkhuang 2003-11-25
本生就是阻塞的!现在难办的就是不阻塞!
回复
相关推荐
发帖
网络编程
创建于2007-09-28

1.8w+

社区成员

VC/MFC 网络编程
申请成为版主
帖子事件
创建了帖子
2003-11-25 06:07
社区公告
暂无公告