非阻塞套接字实现的文件传输程序

作者&投稿:枕伯 (若有异议请与网页底部的电邮联系)
C++,socket,如何将套接字设置为阻塞模式~

(1)好像默认就是阻塞模式;
(2)用ioctlsocket();例如如果需要将cs设置为阻塞模式:
unsigned long ul=0;
ioctlsocket(cs,FIONBIO,&ul);
(3)若要设置为非阻塞模式:
unsigned long ul=1;//只要是非0值都可以
ioctlsocket(cs,FIONBIO,&ul);

不能立即返回,阻塞套接字要等到收到指定数据后才返回。

以前写的有一些错误
希望能对你有些帮助

// TCPDlg.h : header file
//

#if !defined(AFX_TCPDLG_H__E2F8748A_67A9_47EA_981E_1A2A72E09154__INCLUDED_)
#define AFX_TCPDLG_H__E2F8748A_67A9_47EA_981E_1A2A72E09154__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

/////////////////////////////////////////////////////////////////////////////
// CTCPDlg dialog
#define WM_CLIENT WM_USER + 101
#include "MyEdit.h"
#include "onnect.h"
#include "XPButton.h"
typedef struct ZyMsg
{ char control[1];
char filename[256];
int length;
}Msg;
class CTCPDlg : public CDialog
{
// Construction
public:
BOOL Start;
void OUTEXception(int Error);
CTCPDlg(CWnd* pParent = NULL); // standard constructor
SOCKET COnnect;
Connect dlg;
int response;
Msg msg;
CMyEdit Edit1;
CMyEdit Edit2;
CXPButton Button1;
CXPButton Button2;
CXPButton Button3;
CXPButton Button4;
CXPButton Button5;
DWORD sytart;
BOOL rec;
// Dialog Data
//{{AFX_DATA(CTCPDlg)
enum { IDD = IDD_TCP_DIALOG };
// NOTE: the ClassWizard will add data members here
//}}AFX_DATA

// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CTCPDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL

// Implementation
protected:
HICON m_hIcon;

// Generated message map functions
//{{AFX_MSG(CTCPDlg)
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
afx_msg void OnButton1();
afx_msg void OnButton2();
afx_msg void OnButton3();
afx_msg void OnButton4();
afx_msg void OnButton5();
//}}AFX_MSG
afx_msg void OnClient(WPARAM wParam,LPARAM lParam);
DECLARE_MESSAGE_MAP()
};

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_TCPDLG_H__E2F8748A_67A9_47EA_981E_1A2A72E09154__INCLUDED_)

// TCPDlg.cpp : implementation file
//

#include "stdafx.h"
#include "TCP.h"
#include "TCPDlg.h"
#include "mmsystem.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
CAboutDlg();

// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA

// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL

// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CTCPDlg dialog

CTCPDlg::CTCPDlg(CWnd* pParent /*=NULL*/)
: CDialog(CTCPDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CTCPDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
Start=false;
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CTCPDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CTCPDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CTCPDlg, CDialog)
//{{AFX_MSG_MAP(CTCPDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON1, OnButton1)
ON_BN_CLICKED(IDC_BUTTON2, OnButton2)
ON_BN_CLICKED(IDC_BUTTON3, OnButton3)
ON_BN_CLICKED(IDC_BUTTON4, OnButton4)
ON_BN_CLICKED(IDC_BUTTON5, OnButton5)
//}}AFX_MSG_MAP
ON_MESSAGE(WM_CLIENT,OnClient)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CTCPDlg message handlers

BOOL CTCPDlg::OnInitDialog()
{
CDialog::OnInitDialog();

// Add "About..." menu item to system menu.

// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);

CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}

// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
Edit1.SubclassDlgItem(IDC_EDIT1,this);
Edit2.SubclassDlgItem(IDC_EDIT2,this);
Button1.SubclassDlgItem(IDC_BUTTON1,this);
Button2.SubclassDlgItem(IDC_BUTTON2,this);
Button3.SubclassDlgItem(IDC_BUTTON3,this);
Button4.SubclassDlgItem(IDC_BUTTON4,this);
Button5.SubclassDlgItem(IDC_BUTTON5,this);
// TODO: Add extra initialization here
response=dlg.DoModal();
if(response!=IDOK)
this->OnOK();
this->COnnect=::socket(AF_INET,SOCK_STREAM,0);
sockaddr_in add;
add.sin_addr.S_un.S_addr = inet_addr(dlg.m_edit1);
add.sin_port=::htons(::atof(dlg.m_edit2.GetBuffer(dlg.m_edit2.GetLength())));
add.sin_family=AF_INET;
int timeout =5000*3;
setsockopt(this->COnnect,SOL_SOCKET,SO_RCVTIMEO,(char *)&timeout, // 设置接收超时
sizeof(timeout));
timeout = 5000*3;
setsockopt(this->COnnect,SOL_SOCKET,SO_SNDTIMEO,(char *)&timeout, sizeof(timeout)); //设置发送超时
response=::connect(this->COnnect,(sockaddr *)&add,sizeof(sockaddr_in));
if(response==SOCKET_ERROR)
{
AfxMessageBox("连接服务器失败");
int error=::GetLastError();
this->OUTEXception(error);
}
else
{
AfxMessageBox("连接服务器");
}
WSAAsyncSelect(this->COnnect,m_hWnd,WM_CLIENT,FD_READ);
int nRecvBuf=3200*1024;//设置为32K
response=setsockopt(this->COnnect,SOL_SOCKET,SO_RCVBUF,(const char*)&nRecvBuf,sizeof(int));
if(response==SOCKET_ERROR)
{
int error=::GetLastError();
this->OUTEXception(error);

}
return TRUE; // return TRUE unless you set the focus to a control
}

void CTCPDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}

// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.

void CTCPDlg::OnPaint()
{
CPaintDC dc(this);
CBitmap a;
a.LoadBitmap(IDB_BITMAP3);
CBrush b(&a);
CRect rect;
GetClientRect(&rect);
dc.FillRect(&rect,&b);
if (IsIconic())
{
CPaintDC dc(this); // device context for painting

SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

// Center icon in Client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;

// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}

// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CTCPDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}

void CTCPDlg::OnButton1()
{
// TODO: Add your control notification handler code here
CString str,s;
this->GetDlgItem(IDC_EDIT2)->GetWindowText(str);
str="客户端:"+str+"\r\n";;
msg.control[0]='M';
msg.length=str.GetLength();
response=::send(this->COnnect,(char *)&msg,sizeof(Msg),0);
response=::send(this->COnnect,str.GetBuffer(str.GetLength()),str.GetLength(),0);
if(response==SOCKET_ERROR)
{
int error=::GetLastError();
this->OUTEXception(error);
}
this->GetDlgItem(IDC_EDIT1)->GetWindowText(s);
str=s+str;
this->GetDlgItem(IDC_EDIT1)->SetWindowText(str);
this->GetDlgItem(IDC_EDIT2)->SetWindowText("");
}

void CTCPDlg::OUTEXception(int Error)
{
switch(Error)
{
case WSANOTINITIALISED:AfxMessageBox("A successful AfxSocketInit must occur before using this API.");break;
case WSAENETDOWN :AfxMessageBox("The Windows Sockets implementation detected that the network subsystem failed.");break;
case WSAEACCES:AfxMessageBox("The requested address is a broadcast address, but the appropriate flag was not set.");break;
case WSAEINPROGRESS:AfxMessageBox("A blocking Windows Sockets operation is in progress.");break;
case WSAEFAULT:AfxMessageBox("The lpBuf or lpSockAddr parameters are not part of the user address space,");break;
case WSAEINVAL:AfxMessageBox(" The host name is invalid.");break;
case WSAENETRESET:AfxMessageBox("The Cliention must be reset because the Windows Sockets implementation dropped it.");break;
case WSAENOBUFS :AfxMessageBox("The Windows Sockets implementation reports a buffer deadlock.");break;
case WSAENOTCONN:AfxMessageBox("The socket is not Cliented (SOCK_STREAM only).");break;
case WSAENOTSOCK:AfxMessageBox("The descriptor is not a socket.");break;
case WSAEOPNOTSUPP :AfxMessageBox(" MSG_OOB was specified, but the socket is not of type SOCK_STREAM");break;
case WSAESHUTDOWN:AfxMessageBox("The socket has been shut down;");break;
case WSAEWOULDBLOCK :AfxMessageBox("The socket is marked as nonblocking and the requested operation would block.");break;
case WSAEMSGSIZE :AfxMessageBox("The socket is of type SOCK_DGRAM, and the datagram is larger than the maximum supported by the Windows Sockets implementation.");break;
case WSAECONNABORTED:AfxMessageBox("The virtual circuit was aborted due to timeout or other failure.");break;
case WSAECONNRESET:AfxMessageBox("The virtual circuit was reset by the remote side.");break;
case WSAEADDRNOTAVAIL:AfxMessageBox("The specified address is not available from the local machine.");break;
case WSAEAFNOSUPPORT :AfxMessageBox("Addresses in the specified family cannot be used with this socket.");break;
case WSAEDESTADDRREQ:AfxMessageBox("A destination address is required.");break;
case WSAENETUNREACH :AfxMessageBox("The network cannot be reached from this host at this time.");break;
case WSAEADDRINUSE :AfxMessageBox("The specified address is already in use.");break;
case WSAECONNREFUSED :AfxMessageBox("The attempt to Client was rejected.");break;
case WSAEISCONN :AfxMessageBox("The socket is already Cliented.");break;
case WSAEMFILE :AfxMessageBox("No more file descriptors are available.");break;
case WSAETIMEDOUT:AfxMessageBox("Attempt to Client timed out without establishing a Cliention.");break;
case WSAEINTR:AfxMessageBox("The (blocking) Windows Socket 1.1 call was canceled through WSACancelBlockingCall.");break;
case WSAEALREADY: AfxMessageBox("A nonblocking Client call is in progress on the specified socket");break;
default:AfxMessageBox("不明原因");
}
}

void CTCPDlg::OnButton2()
{
// TODO: Add your control notification handler code here
CString str,s;
CFileDialog dlg(TRUE,NULL,NULL,NULL,"位图文件(*.bmp)|*.bmp|文本文件(*.txt)|*.txt|All Files(*.*)|*.*||");
if(dlg.DoModal()==IDOK)
{
str=dlg.GetPathName();
s=dlg.GetFileName();
}
else
return;
CFile f;
char buf[512];
int Read;
f.Open(str,CFile::modeReadWrite);
msg.control[0]='F';
msg.length=f.GetLength();
::strcpy(msg.filename,s.GetBuffer(s.GetLength()));
response=::send(this->COnnect,(char *)&msg,sizeof(Msg),0);
str="";
while(1)
{
Read=f.Read(buf,512);
if(Read==0)
break;
::send(this->COnnect,buf,Read,0);
}

}

void CTCPDlg::OnButton3()
{
// TODO: Add your control notification handler code here
msg.control[0]='C';
msg.length=1;
::send(this->COnnect,(const char *)&msg,sizeof(Msg),0);
}
void CTCPDlg::OnClient(WPARAM wParam,LPARAM lParam)
{
switch(WSAGETSELECTEVENT(lParam))
{
case FD_READ:
int read;
char lpBuf[2048];
CString str,m_Path;
char* A1="F";
char* A2="M";
char* A3="C";
CString s,t;
int re;
CFile f;
if(Start==false)
{
::WSAAsyncSelect(COnnect,m_hWnd,0,0);
::recv(COnnect,(char*)&msg,sizeof(Msg),0);
re=msg.length;
s=msg.control[0];
if(!::strcmp(s.GetBuffer(s.GetLength()),A1))
{
BROWSEINFO bi;
char name[MAX_PATH];
ZeroMemory(&bi,sizeof(BROWSEINFO));
bi.hwndOwner=GetSafeHwnd();
bi.pszDisplayName=name;
bi.lpszTitle="浏览文件夹";
bi.ulFlags=BIF_RETURNONLYFSDIRS;
LPITEMIDLIST idl=SHBrowseForFolder(&bi);
sytart=::GetTickCount();
if(idl==NULL)
{
rec=false;
m_Path="";
}
else
{
BOOL Sh=SHGetPathFromIDList(idl,str.GetBuffer(MAX_PATH));
str.ReleaseBuffer();
m_Path=str;
if(str.GetAt(str.GetLength()-1)!='\\')
m_Path+="\\";
UpdateData(FALSE);
}
m_Path=m_Path+msg.filename;
f.Open(m_Path,CFile::modeCreate|CFile::modeReadWrite);
Start=true;
::WSAAsyncSelect(COnnect,m_hWnd,WM_CLIENT,FD_READ);
int nRecvBuf=re;//设置为32K
response=setsockopt(COnnect,SOL_SOCKET,SO_RCVBUF,(const char*)&nRecvBuf,sizeof(int));
if(response==SOCKET_ERROR)
{
int error=::GetLastError();
this->OUTEXception(error);

}
}
if(Start)
while(1)
{
read=::recv(COnnect,(char*)lpBuf,2048,0);
if(read>0)
{
re=re-read;
f.Write(lpBuf,read);
}
if((::GetTickCount()-sytart)>5*60*1000)
{
Start=false;
AfxMessageBox("接收数据失败!!");
break;
}
if(read==SOCKET_ERROR&&::GetLastError()==WSAEWOULDBLOCK)
{
break;
}
if(read==SOCKET_ERROR&&::GetLastError()!=WSAEWOULDBLOCK)
{
Start=false;
AfxMessageBox("接收数据失败!!");
break;
}
if(re==0)
{
if(rec==false)
{ AfxMessageBox(msg.filename);
f.Close();
f.Remove(msg.filename);
rec=true;
Start=false;
break;
}
AfxMessageBox("接受数据完成");
Start=false;
f.Close();
break;
}
}
if(!::strcmp(s.GetBuffer(s.GetLength()),A2))
{
::sndPlaySound("msg.wav",SND_ASYNC);
read=::recv(COnnect,lpBuf,512,0);
t=lpBuf;
this->GetDlgItem(IDC_EDIT1)->GetWindowText(str);
str=str+t.Left(read);
if(!str.IsEmpty())
this->GetDlgItem(IDC_EDIT1)->SetWindowText(str);
AfxGetMainWnd()->FlashWindow(TRUE);
Start=false;
break;
}
}
}
}

void CTCPDlg::OnButton4()
{
// TODO: Add your control notification handler code here
msg.control[0]='C';
msg.length=2;
::send(this->COnnect,(const char *)&msg,sizeof(Msg),0);
}

void CTCPDlg::OnButton5()
{
// TODO: Add your control notification handler code here
msg.control[0]='C';
msg.length=3;
::send(this->COnnect,(const char *)&msg,sizeof(Msg),0);
}

大哥。你为什么不去C++里提问呢?那里高手很多!会很快帮你解决的!

嗯,好像我们的课程设计也是类似这个

留名关注下,说不定用得上^_^


套接字建立连接过程
我们先看一下最初的过程,服务器端通过 socket,bind 和 listen 完成了被动套接字的准备工作,被动的意思就是等着别人来连接,然后调用 accept,就会阻塞在这里,等待客户端的连接来临;客户端通过调用 socket 和 connect 函数之后,也会阻塞。接下来的事情是由操作系统内核完成的,更具体一点的说,是操作系统内核网络协议栈...

什么是阻塞式和非阻塞io流?
阻塞IO:socket 的阻塞模式意味着必须要做完IO 操作(包括错误)才会返回。非阻塞IO:非阻塞模式下无论操作是否完成都会立刻返回,需要通过其他方式来判断具体操作是否成功。两者区别:所谓阻塞方式的意思是指, 当试图对该文件描述符进行读写时, 如果当时没有东西可读,或者暂时不可写, 程序就进入等待 状态...

非阻塞套接字实现的文件传输程序
异步传输模式下(推荐WSAAnsyncSelect模式,也可用其他异步模式)可以实现点对点的文件传输(可以实现大文件1G以上传输)。难点:如何有序地传输文件块?即:异步模式下如何实现同步?提示... 异步传输模式下(推荐WSAAnsyncSelect模式,也可用其他异步模式)可以实现点对点的文件传输(可以实现大文件1G以上传输)。难点:如何有序地...

UDP堵塞怎么解决???
include <unistd.h> include ..sockfd = socket(AF_INET, SOCK_DGRAM, 0);fcntl(sockfd, F_SETFL, O_NONBLOCK);..如果尝试着从一个非阻塞的套接字读信息并且没有任何数据,它不允许阻 塞--它将返回 -1 并将 errno 设置为 EWOULDBLOCK。 但是...

阻塞和非阻塞网络io有什么区别
阻塞IO和非阻塞IO,主要区别在于第一个阶段。也即是阻塞IO,在套接字缓冲区没准备好的情况下,会一直等待。而非阻塞IO,在套接字缓冲区没准备好时,会立即返回。获取IO数据,分为两个阶段,一是套接字缓冲区准备阶段;二是数据拷贝阶段(内核将数据从socket缓冲区拷贝到用户空间)。套接字的默认状态...

Socket编程
\/\/等待客户请求到来;当请求到来后,接受连接请求,返回一个新的对应于此次连接的套接字(accept)。\/\/此时程序在此发生阻塞 char sendBuf[100];sprintf(sendBuf,"Welcome %s to http:\/\/www.sunxin.org",inet_ntoa(addrClient.sin_addr));\/\/用返回的套接字和客户端进行通信(send\/recv)。send(...

IO模型及select,poll,epoll和kqueue的区别
异步非阻塞直接在完成后通知,用户进程只需要发起一个IO操作然后立即返回,等IO操作真正的完成以后,应用程序会得到IO操作完成的通知,此时用户进程只需要对数据进行处理就好了,不需要进行实际的IO读写操作,因为真正的IO读取或者写入操作已经由内核完成了。1 blocking I\/O 这个不用多解释吧,阻塞套接字。下图是它调用过程...

什么叫套接字超时~
在涉及套接字的I\/O操作上设置超时的方法有三种:1:调用alarm,它在指定的超时期满时产生SIGALRM信号。这个方法涉及信号处理,而信号处理在不同的实现上存在差异,而且可能干扰进程中现有的alarm调用。2:在select中阻塞等待I\/O(select有内置的时间限制),依次代替直接阻塞在read或write调用上。(linux2.6...

用socket创建的套接字默认是阻塞的还是非阻塞的
非堵塞的。但是当调用.accpet方法的时候这个是堵塞的。等待监听由客户端来的连接。

面试必问的epoll技术,从内核源码出发彻底搞懂epoll
ep_item_poll函数里面,调用目标文件的poll函数,这个函数针对不同的目标文件而指向不同的函数,如果目标文件为套接字的话,这个poll就指向sock_poll,而如果目标文件为tcp套接字来说,这个poll就是tcp_poll函数。虽然poll指向的函数可能会不同,但是其作用都是一样的,就是获取目标文件当前产生的事件位,并且将监听项绑定...

印江土家族苗族自治县17080829825: 非阻塞套接字实现的文件传输程序 -
木良维普: 既然你用异步了,就没必要有序,等份分割文件,让每个线程承包一份.只需要在传输时编号就行了,然后将编号一起穿过去.第一个包要包含整个文件的大小(实际上是份数) 接收端分文件存放,最后合并,这需要一个列表,用来记录所有的文件是否都到达 至于具体怎么实现,可以参照 www.pudn.com

印江土家族苗族自治县17080829825: 什么是winsock -
木良维普: WINSOCK编程 目前,Internet已成为世界上最大的TCP/IP网络.早期的站点是UNIX机器,一组称为Berkeley插口的约定成为INTERNET上UNIX机器之间利用TCP/IP进行通信的标准.其他操作系统也用TCP/IP进行通信,这极大地促进了...

印江土家族苗族自治县17080829825: 网络编程中阻塞和非阻塞socket的区别 -
木良维普: 阻塞:一般的I/O操作可以在新建的流中运用.在服务器回应前它等待客户端发送一个空白的行.当会话结束时,服务器关闭流和客户端socket.如果在队列中没有请示将会出现什么情况呢?那个方法将会等待一个的到来.这个行为叫阻塞.accept()...

印江土家族苗族自治县17080829825: linux网络编程中阻塞和非阻塞socket的区别 -
木良维普: 阻塞的是意思是这样:read函数读的时候,如果此时数据包没有来,那就程序就会暂停执行,在read函数里面暂停.它如何继续执行呢?那就是数据包来之后它继续执行.非阻塞就是说,如何执行read函数的时候,数据包没有,那么read函数返回没有读到任何东西,如果执行read函数时候恰好有数据包,那么read函数将返回读到的数据包.也就是说,阻塞的socket使用read的时候,你都能保证读到数据包.而非阻塞就不一定了,所以往往非阻塞需要配合循环,不停的读,或者设置一个超时.如果读了几次,或者等待了多少秒没有读到,就超时.阻塞的,无法控制时间.

印江土家族苗族自治县17080829825: 如何实现一个非阻塞的socket -
木良维普: 所谓非阻塞模式就是,当主线程做一个操作的时候不会阻塞,而是可以继续往下执行别的代码.比如说如果你主线程用socket发送一段数据,这是需要一定的时间的,这个时候你的主线程就被阻塞了,必须等发送完了才能执行其它的代码.而假如你把这个发送的操作交给另外的一个线程去做,那么主线程就可以继续干别的了.所以说在要想做到非阻塞,基本上就是用多线程去实现了

印江土家族苗族自治县17080829825: Socket阻塞模式和非阻塞模式的区别 -
木良维普: 阻塞调用是指调用结果返回之前,当前线程会被挂起.函数只有在得到结果之后才会返回.有人也许会把阻塞调用和同步调用等同起来,实际上他是不同的.对于同步调用来说,很多时候当前线程还是激活的,只是从逻辑上当前函数没有返回而...

印江土家族苗族自治县17080829825: python的socket的非阻塞实现 -
木良维普: setblocking(0)之后就是非阻塞的.select模块只是说能够同时处理多个socket,至于这些socket是阻塞还是非阻塞,都没有关系.当然从性能上考虑,现在的趋势是select+非阻塞.

印江土家族苗族自治县17080829825: 【求教】如何使用socket的非阻塞模式? -
木良维普: 一般分为 多线程阻塞 非阻塞 / 单线程阻塞 /单一线程阻塞 非阻塞这三种 简单地说 每一个SS请求 serversocket 需要一个字节码缓冲区来读取和写入字节码 然后转换输出文本 理论上可以用一个非常大的buffer区来解决这个问题 但如果是第一种 多...

印江土家族苗族自治县17080829825: MFC中网络编程,利用套接字的过程. -
木良维普: 服务器端 一、创建服务器套接字(CREATE). 二、服务器套接字进行信息绑定(BIND),并开始监听连接(LISTEN). 三、接受来自客户端的连接请求(ACCEPT),并创建接收进程. 四、开始数据传输(SEND、RECEIVE). 五...

印江土家族苗族自治县17080829825: socket中阻塞与非阻塞如何理解 -
木良维普: 这个问题涉及三方面,一个是阻塞本身的定义,一个是阻塞现象,一个是阻塞模式设定 阻塞,就是阻挡,禁止做某工作 当系统出现阻塞现象时, 如果设置了阻塞模式,则当前程序会等待阻塞现象消失,然后继续做事情 如果设置了非阻塞模式,则,当前程序会马上返回相应的错误,停止做事情 以上只是白话描述,细节内容还是要多读书去理解

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网