社区
网络编程
帖子详情
50分! 非阻塞套接字如何使用?谁能提供一个C++例子?
linfeng1216
2003-07-18 01:47:01
50分! 非阻塞套接字如何使用?谁能提供一个C++例子?
...全文
232
13
打赏
收藏
50分! 非阻塞套接字如何使用?谁能提供一个C++例子?
50分! 非阻塞套接字如何使用?谁能提供一个C++例子?
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
13 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
shines77
2003-09-20
打赏
举报
回复
阅
fre1714
2003-07-31
打赏
举报
回复
非阻塞的客户机程序:
#include <winsock2.h>
#include <stdio.h>
#define MYPORT 5550 // 定义默认通信端口
#define LINELEN 128 // 定义一行数据的最大长度
void main(int argc, char **argv)
{
WSADATA wsaData;
SOCKET s;
SOCKADDR_IN ServerAddr;
int Ret, length;
char buf[LINELEN];
fd_set writefds; // 等待可写性检查的套接口结构体
unsigned long ul = 1;
struct timeval timeout; // 最多等待时间
// 对主函数的参数进行处理
switch(argc)
{
case 1:
argv[1] = "127.0.0.1"; // 定义一个默认的IP地址
break;
case 2:
argv[1]
argv[2]
break;
default:
printf("argument error!\n");
exit(1);
}
printf("\n------------------非阻塞模式的套接字(客户机)------------------\n\n");
// 初始化 Winsock 2.2 版本
if ((Ret = WSAStartup(MAKEWORD(2,2), &wsaData)) != 0)
{
printf("WSAStartup failed with error %d\n", Ret);
return;
}
// 创建一个新套接字来建立客户机连接
if ((s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
{
printf("socket failed with error %d\n", WSAGetLastError());
WSACleanup();
return;
}
// 设置套接字为非阻塞模式
Ret = ioctlsocket(s, FIONBIO, (unsigned long *) &ul);
if (Ret == SOCKET_ERROR)
{
printf("ioctlsocket failed with error %d\n", WSAGetLastError());
}
else
{
printf("set nonblock mode successed, return value %d\n", Ret);
}
// 初始化一个 SOCKADDR_IN 结构
ServerAddr.sin_family = AF_INET;
ServerAddr.sin_port = htons(MYPORT);
ServerAddr.sin_addr.s_addr = inet_addr(argv[1]); // 定义服务器地址
// 用套接字 s 来创建一个到服务器的连接
Ret = connect(s, (SOCKADDR *) &ServerAddr, sizeof(ServerAddr));
if (WSAGetLastError() != WSAEWOULDBLOCK)
{
printf("connect failed with error %d\n", WSAGetLastError());
closesocket(s);
WSACleanup();
return;
}
else
{
// 和服务器的连接成功
printf("connect to %s on %d succeeded.\n", argv[1], MYPORT);
printf("please input send data....\n");
// 定义Select() 的最多等待时间
timeout.tv_sec = 0;
timeout.tv_usec = 500;
while (1)
{
FD_ZERO(&writefds);
FD_SET(s, &writefds);
// 查询套接口的可写性
Ret = select( 0, NULL, &writefds, NULL, &timeout);
if (Ret > 0)
{
if (FD_ISSET(s, &writefds))
{
// 循环:从输入流中取数据
while (fgets(buf, sizeof(buf), stdin))
{
buf[LINELEN] = '\0'; // 在字符串最后加终止符
length = strlen(buf); // 实际发送字节数
// 如果输入是回车,则结束程序
if (buf[0] == '\n')
{
closesocket(s);
WSACleanup();
return;
}
// 发送数据
if ((Ret = send(s, buf, length, 0)) == SOCKET_ERROR)
{
printf("send failed with error %d\n", WSAGetLastError());
closesocket(s);
WSACleanup();
return;
}
}
}
}
}
}
// 关闭套接字
closesocket(s);
// 释放由 winsock 分配的资源
WSACleanup();
}
fre1714
2003-07-31
打赏
举报
回复
非阴塞的服务器程序:
#include <winsock2.h>
#include <stdio.h>
#define MYPORT 5550 // 定义默认通信端口
void main(void)
{
WSADATA wsaData;
SOCKET ListeningSocket; // 服务器套接字
SOCKET NewConnection; // 客户机套接字
SOCKADDR_IN ServerAddr;
SOCKADDR_IN ClientAddr;
int Ret, ClientAddrLen;
char DataBuffer[1024]; // 接收数据的缓冲区
fd_set readfds; // 等待可读性检查的套接口结构体
unsigned long ul = 1;
struct timeval timeout; // 最多等待时间
printf("\n------------------非阻塞模式的套接字(服务器)------------------\n\n");
// 初始化 Winsock 2.2 版本
if ((Ret = WSAStartup(MAKEWORD(2,2), &wsaData)) != 0)
{
printf("WSAStartup failed with error %d\n", Ret);
return;
}
// 创建一个新套接字来监听客户机的连接
if ((ListeningSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
{
printf("socket failed with error %d\n", WSAGetLastError());
WSACleanup();
return;
}
// 初始化一个 SOCKADDR_IN 结构
ServerAddr.sin_family = AF_INET; // 使用IP地址族
ServerAddr.sin_port = htons(MYPORT); // 通信端口(5550)
ServerAddr.sin_addr.s_addr = htonl(INADDR_ANY); // 使用自己的IP地址,实际默认为0
// 将这个地址信息和套接字关联起来
if (bind(ListeningSocket, (SOCKADDR *)&ServerAddr, sizeof(ServerAddr)) == SOCKET_ERROR)
{
printf("bind failed with error %d\n", WSAGetLastError());
closesocket(ListeningSocket);
WSACleanup();
return;
}
// 将套接字转入监听模式,监听客户机的连接,指定最大队列长度为5
if (listen(ListeningSocket, 5) == SOCKET_ERROR)
{
printf("listen failed with error %d\n", WSAGetLastError());
closesocket(ListeningSocket);
WSACleanup();
return;
}
// 设置套接字为非阻塞模式
Ret = ioctlsocket(ListeningSocket, FIONBIO, (unsigned long *) &ul);
if (Ret == SOCKET_ERROR)
{
printf("ioctlsocket failed with error %d\n", WSAGetLastError());
}
else
{
printf("set nonblock mode successed, return value %d\n", Ret);
}
printf("waiting for connection on port %d....\n", MYPORT);
// 定义Select() 的最多等待时间
timeout.tv_sec = 0;
timeout.tv_usec = 500;
while (1)
{
FD_ZERO(&readfds); // 对结构体进行初始化
FD_SET(ListeningSocket, &readfds); // 把套接字加入集合
// 查询套接口的可读性
Ret = select(0, &readfds, NULL, NULL, &timeout);
if (Ret > 0)
{
if (FD_ISSET(ListeningSocket, &readfds))
{
ClientAddrLen = sizeof(ClientAddr);
// 当有连接请求到达时,接受一个新连接
if ((NewConnection = accept(ListeningSocket, (SOCKADDR *) &ClientAddr,
&ClientAddrLen)) == INVALID_SOCKET)
{
printf("accept failed with error %d\n", WSAGetLastError());
closesocket(ListeningSocket);
WSACleanup();
exit(1);
}
printf("got a connection from %s .\n", inet_ntoa(ClientAddr.sin_addr));
// 循环
while(1)
{
// FD_ZERO(&readfds);
FD_SET(NewConnection, &readfds);
// 第二次检查套接口的可读性,等待时间设为空,否则会出现超时错误
Ret = select(0, &readfds, NULL, NULL, NULL);
if (FD_ISSET(NewConnection, &readfds))
{
// 接收数据
Ret = recv(NewConnection, DataBuffer, sizeof(DataBuffer)-1, 0);
if (Ret == SOCKET_ERROR || Ret == 0)
{
// 接收错误
printf("recv failed with error %d\n", WSAGetLastError());
closesocket(NewConnection);
WSACleanup();
return ;
}
else
{
DataBuffer[Ret] = '\0';
printf("received %d byte: %s", (Ret-1), DataBuffer);
}
}
}
}
}
}
// 关闭套接字
closesocket(NewConnection);
// 释放由 winsock 分配的资源
WSACleanup();
}
fre1714
2003-07-31
打赏
举报
回复
我给你一个
linfeng1216
2003-07-28
打赏
举报
回复
哪里看得出是MFC?
Healer
2003-07-21
打赏
举报
回复
不是说C++吗?? 怎么是MFC的代码??
linfeng1216
2003-07-21
打赏
举报
回复
哇!楼上的老大是谁啊?五颗红星可是我这辈子的梦想呢!佩服死了!!
非常感谢你的代码,但我还是有点看不懂,要是有中文注释就更好了。
masterz
2003-07-20
打赏
举报
回复
CAsyncSocketEx 来自 http://www.codeproject.com/internet/casyncsocketex.asp
以上是vc++客户端,server 是java写的
/**
* <p>Title: </p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2003</p>
* <p>Company: Home</p>
* @author Onega
* @version 1.0
*/
import java.io.*;
import java.net.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Netserver extends JFrame implements ActionListener,WindowListener
{
public static int readTurn = 0;
private JButton addTurn=new JButton("Add turn");
public Netserver()
{
addWindowListener(this);
Container c = this.getContentPane();
c.setLayout(new FlowLayout());
c.add(addTurn);
addTurn.addActionListener(this);
this.setSize(400,300);
this.setVisible(true);
this.show();
}
public void actionPerformed(ActionEvent e)
{
if (e.getSource() == addTurn)
{
readTurn++;
showReadTurn();
}
}
public static void showReadTurn()
{
System.out.println("current readturn="+readTurn);
}
int portnum = 5555;
public static void main(String args[])
{
new Netserver().work();
}
void work()
{
try
{
ServerSocket server_socket=new ServerSocket(portnum);
System.out.println("listen on "+portnum);
while(true)
{
Socket socket = server_socket.accept();
System.out.println("New connection accepted " +
socket.getInetAddress() +
":" + socket.getPort());
RequestHandler rh = new RequestHandler(socket);
Thread th = new Thread(rh);
th.start();
}
}
catch(IOException eio)
{
eio.printStackTrace();
}
}
public void windowActivated(WindowEvent we){}
public void windowClosed(WindowEvent we){}
public void windowDeactivated(WindowEvent we){}
public void windowClosing(WindowEvent we)
{
this.hide();
this.dispose();
System.exit(0);
}
public void windowOpened(WindowEvent we){}
public void windowIconified(WindowEvent we){}
public void windowDeiconified(WindowEvent we){}
}
class RequestHandler implements Runnable
{
Socket conn;
InputStream input;
OutputStream output;
BufferedReader br;
byte[] buf;
public RequestHandler(Socket s)
{
try
{
conn=s;
this.input = conn.getInputStream();
this.output = conn.getOutputStream();
buf = new byte[256];
}
catch(Exception e)
{
e.printStackTrace();
}
}
public int readLength() throws Exception
{
byte[] b = new byte[4];
input.read(b);
int nret = 0;
for (int i = b.length - 1; i >= 0; i--)
{
nret = nret * 256 + b[i];
}
return nret;
}
private void readFile() throws Exception
{
int ntotallength = readLength();
int nread = 1;
int tread = 0;
byte b[] = new byte[1024];
File f = new File("c:\\a.zip");
FileOutputStream fos = new FileOutputStream(f);
while (nread > 0 && ntotallength > tread)
{
nread = input.read(b);
if (nread > 0)
{
tread += nread;
fos.write(b, 0, nread);
}
if(Math.random()<0.1)
Thread.currentThread().sleep(100);
}
fos.close();
System.out.println("total length:" + ntotallength + " read length:" +
tread);
}
private void sendFile() throws Exception
{
File f=new File("c:\\a.jpg");
long len = f.length();
FileInputStream fis=new FileInputStream(f);
int ntmp = (int)len;
byte b[]=new byte[ntmp];
for(int i=0;i<4;i++)
{
b[i] = (byte)(ntmp&0xff);
ntmp = ntmp /256;
}
output.write(b,0,4);
fis.read(b);
fis.close();
int nsend =0;
int tsend =0;
output.write( b, tsend, (int)(len-tsend));
System.out.println("file length:"+len+" send complete");
}
public void run()
{
int receive_count=0;
int readcount = 1;
try
{
System.out.println("connection accepted " +
conn.getInetAddress() +
":" + conn.getPort());
readFile();
sendFile();
input.close();
output.close();
conn.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
masterz
2003-07-20
打赏
举报
回复
#include "StdAfx.h"
#include ".\mysock.h"
#include <strsafe.h>
#include <memory>
CMySock::CMySock(void)
: m_nReceive(0)
, m_nSend(0),m_pSendBuf(NULL),m_nSendBufLen(0),m_pStream(NULL)
{
}
CMySock::~CMySock(void)
{
if(m_pStream)
m_pStream->Release();
}
void Verbose(LPCTSTR fmtstr, ... )
{
TCHAR tstr[10240];
va_list args;
va_start( args, fmtstr );
int nBuf = StringCchVPrintf( tstr,sizeof(tstr)/sizeof(tstr[0]), fmtstr, args );
va_end( args );
OutputDebugString(tstr);
}
void CMySock::OnConnect(int nErrorCode)
{
Verbose("%s",__FUNCTION__);
}
void CMySock::OnReceive(int nErrorCode)
{
Verbose("%s",__FUNCTION__);
if (OnAsyncError(nErrorCode, __FUNCTION__))
return;
if(!m_pStream)
{
HRESULT hr=CreateStreamOnHGlobal(NULL,TRUE,&m_pStream);
}
if(m_pStream)
{
char buf[1024];
int nret = 1;
ULONG uwrite;
while(nret>0)
{
nret = Receive(buf,sizeof(buf));
if(nret>0)
{
m_pStream->Write(buf,nret,&uwrite);
m_nReceive +=nret;
}
}
}
}
void CMySock::OnSend(int nErrorCode)
{
Verbose("%s",__FUNCTION__);
if (OnAsyncError(nErrorCode, __FUNCTION__))
return;
int nRet = 1;
while(m_nSend<m_nSendBufLen &&nRet>0)
{
nRet =Send(m_pSendBuf+m_nSend,m_nSendBufLen-m_nSend);
if(nRet>0)
m_nSend +=nRet;
}
}
bool CMySock::OnAsyncError(int nErrorCode, LPCSTR sFuncName)
{
if (nErrorCode != 0) {
switch (nErrorCode) {
case WSAECONNRESET:
Verbose("%s errorcode:%d, description:%s",sFuncName,nErrorCode,"WSAECONNRESET");
Close();
return true;
case WSAECONNREFUSED:
Verbose("%s errorcode:%d, description:%s",sFuncName,nErrorCode,"WSAECONNREFUSED");
Close();
return true;
default:
//Verbose("%s errorcode:%d, description:%s",sFuncName,nErrorCode,
// WSAGetLastErrorMessage("Async failure notification", nErrorCode));
break;
}
}
return false;
}
int CMySock::SetSend(const char* lpBuf, int nBufLen, int nFlags)
{
m_nSend = 0;
m_pSendBuf = lpBuf;
if(m_pSendBuf)
m_nSendBufLen = nBufLen;
else
m_nSendBufLen = 0;
Verbose("%s bytes to send:%d",__FUNCTION__,m_nSendBufLen);
return 0;
}
int CMySock::GetReceiveCount(void)
{
return m_nReceive;
}
int CMySock::GetSendCount(void)
{
return m_nSend;
}
void CMySock::OnClose(int nErrorCode)
{
Verbose("%s",__FUNCTION__);
if (OnAsyncError(nErrorCode, __FUNCTION__))
return;
}
char* CMySock::GetReceived(int& nLength)
{
nLength = 0;
if(m_nReceive>0&&m_pStream)
{
std::auto_ptr<char> bufptr(new char[m_nReceive]);
if(bufptr.get())
{
LARGE_INTEGER li_pos ;
ULARGE_INTEGER li_totallength;
li_pos.QuadPart = 0;
li_totallength.QuadPart= 0;
HRESULT hr=m_pStream->Seek(li_pos,STREAM_SEEK_SET,&li_totallength);
ULONG uread=0;
int readtotal =0;
while(readtotal<m_nReceive)
{
m_pStream->Read(bufptr.get()+readtotal,m_nReceive-readtotal,&uread);
if(uread>0)
{
readtotal+=uread;
}
else
break;
}
if(readtotal==m_nReceive)
{
nLength = m_nReceive;
return bufptr.release();
}
}
}
return NULL;
}
masterz
2003-07-20
打赏
举报
回复
#pragma once
#include "asyncsocketex.h"
class CMySock :
public CAsyncSocketEx
{
public:
CMySock(void);
virtual ~CMySock(void);
void OnConnect(int nErrorCode);
void OnReceive(int nErrorCode);
void OnSend(int nErrorCode);
bool OnAsyncError(int nErrorCode, LPCSTR sFuncName);
private:
int m_nReceive;
int m_nSend;
const char* m_pSendBuf;
int m_nSendBufLen;
IStream* m_pStream;
public:
int SetSend( const char* lpBuf, int nBufLen, int nFlags=0);
int GetReceiveCount(void);
int GetSendCount(void);
void OnClose(int nErrorCode);
char* GetReceived(int& nLength);
};
void Verbose(LPCTSTR fmtstr, ... );
linfeng1216
2003-07-20
打赏
举报
回复
谢谢!
c0der
2003-07-18
打赏
举报
回复
http://www.heima21.com/ReadNews.asp?NewsID=228
xwsun
2003-07-18
打赏
举报
回复
up
c++
做的异步通信,
使用
socket的典型
例子
c++
,socket的应用
例子
,能实现发送消息
突破编程_
C++
_网络编程(Windows
套接字
(阻塞模式与
非阻塞
模式))
C++
网络编程:Windows
套接字
(阻塞模式与
非阻塞
模式)
Winsock
套接字
非阻塞
模式小例程 WinSock IO模型
服务器端
使用
非阻塞
套接字
,允许有多个客户接入。客户端
使用
阻塞
套接字
。服务器端循环轮询方式。 /***设
套接字
为
非阻塞
模式***/ unsigned long ul = 1; int nRet=ioctlsocket(sock_server, FIONBIO, &ul); //设置
套接字
非阻塞
模式 if (nRet == SOCKET_ERROR) { cout <<...
异步
非阻塞
套接字
Winsock开发网络通信程序的经典入门
对于许多初学者来说,网络通信程序的开发,普遍的
一个
现象就是觉得难以入手。许多概念,诸如:同步(Sync)/异步(Async),阻塞(Block)/
非阻塞
(Unblock)等,初学者往往迷惑不清,只知其所以而不知起所以然。 异步方式指的是发送方不等接收方响应,便接着发下个数据包的通信方式;而同步指发送方发出数据后,等收到接收方发回的响应,才发下
一个
数据包的通信方式。 阻塞
套接字
是
24-TCP三次握手:怎么
使用
套接字
格式建立连接?
1、TCP三次握手:怎么
使用
套接字
格式建立连接? 上一讲介绍了 IPv4、IPv6 以及本地
套接字
格式; 这一讲我们来讲一讲怎么
使用
这些
套接字
格式完成连接的建立,当然,经典的 TCP 三次握手理论也会贯穿其中。 希望经过这一讲的讲解,你会牢牢记住 TCP 三次握手和客户端、服务器模型。 1.1、服务端准备连接的过程 1.1.1、创建
套接字
创建
套接字
函数: int socket(int domain, int type, int protocol) domain 就是指 PF_INET、PF_IN
网络编程
18,357
社区成员
64,171
社区内容
发帖
与我相关
我的任务
网络编程
VC/MFC 网络编程
复制链接
扫一扫
分享
社区描述
VC/MFC 网络编程
c++
c语言
开发语言
技术论坛(原bbs)
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章