日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux 全双工 wifi热点,Linux中的同时套接字读/写(“全双工”)(特别是aio)

發布時間:2023/12/4 linux 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux 全双工 wifi热点,Linux中的同时套接字读/写(“全双工”)(特别是aio) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

我正在移植構建在ACE Proactor框架之上的應用程序.該應用程序適用于VxWorks和Windows,但在使用librt的內核2.6.X.X的Linux(CentOS 5.5,WindRiver Linux 1.4和3.0)上無法運行.

我把問題縮小到一個非常基本的問題:

應用程序在套接字上開始異步(通過aio_read)讀取操作,然后在同一個套接字上開始異步(通過aio_write)寫入.由于協議是從應用程序結束初始化的,因此無法實現讀取操作.

– 當套接字處于阻塞模式時,永遠不會寫入并且協議“掛起”.

– 使用O_NONBLOCK套接字時,寫入成功,但讀取無限期地返回“EWOULDBLOCK / EAGAIN”錯誤,永遠不會恢復(即使重新啟動AIO操作).

我經歷了多個論壇,無法找到一個明確的答案,說明這是否應該可行(而且我做錯了)或Linux AIO不可能.是否可以放棄AIO并尋求不同的實現(通過epoll / poll / select等)?

附件是一個示例代碼,可以在非阻塞套接字上快速重現問題:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define BUFSIZE (100)

// Global variables

struct aiocb *cblist[2];

int theSocket;

void InitializeAiocbData(struct aiocb* pAiocb, char* pBuffer)

{

bzero( (char *)pAiocb, sizeof(struct aiocb) );

pAiocb->aio_fildes = theSocket;

pAiocb->aio_nbytes = BUFSIZE;

pAiocb->aio_offset = 0;

pAiocb->aio_buf = pBuffer;

}

void IssueReadOperation(struct aiocb* pAiocb, char* pBuffer)

{

InitializeAiocbData(pAiocb, pBuffer);

int ret = aio_read( pAiocb );

assert (ret >= 0);

}

void IssueWriteOperation(struct aiocb* pAiocb, char* pBuffer)

{

InitializeAiocbData(pAiocb, pBuffer);

int ret = aio_write( pAiocb );

assert (ret >= 0);

}

int main()

{

int ret;

int nPort = 11111;

char* szServer = "10.10.9.123";

// Connect to the remote server

theSocket = socket(AF_INET, SOCK_STREAM, 0);

assert (theSocket >= 0);

struct hostent *pServer;

struct sockaddr_in serv_addr;

pServer = gethostbyname(szServer);

bzero((char *) &serv_addr, sizeof(serv_addr));

serv_addr.sin_family = AF_INET;

serv_addr.sin_port = htons(nPort);

bcopy((char *)pServer->h_addr, (char *)&serv_addr.sin_addr.s_addr, pServer->h_length);

assert (connect(theSocket, (const sockaddr*)(&serv_addr), sizeof(serv_addr)) >= 0);

// Set the socket to be non-blocking

int oldFlags = fcntl(theSocket, F_GETFL) ;

int newFlags = oldFlags | O_NONBLOCK;

fcntl(theSocket, F_SETFL, newFlags);

printf("Socket flags: before=%o, after=%o\n", oldFlags, newFlags);

// Construct the AIO callbacks array

struct aiocb my_aiocb1, my_aiocb2;

char* pBuffer = new char[BUFSIZE+1];

bzero( (char *)cblist, sizeof(cblist) );

cblist[0] = &my_aiocb1;

cblist[1] = &my_aiocb2;

// Start the read and write operations on the same socket

IssueReadOperation(&my_aiocb1, pBuffer);

IssueWriteOperation(&my_aiocb2, pBuffer);

// Wait for I/O completion on both operations

int nRound = 1;

printf("\naio_suspend round #%d:\n", nRound++);

ret = aio_suspend( cblist, 2, NULL );

assert (ret == 0);

// Check the error status for the read and write operations

ret = aio_error(&my_aiocb1);

assert (ret == EWOULDBLOCK);

// Get the return code for the read

{

ssize_t retcode = aio_return(&my_aiocb1);

printf("First read operation results: aio_error=%d, aio_return=%d - That's the first EWOULDBLOCK\n", ret, retcode);

}

ret = aio_error(&my_aiocb2);

assert (ret == EINPROGRESS);

printf("Write operation is still \"in progress\"\n");

// Re-issue the read operation

IssueReadOperation(&my_aiocb1, pBuffer);

// Wait for I/O completion on both operations

printf("\naio_suspend round #%d:\n", nRound++);

ret = aio_suspend( cblist, 2, NULL );

assert (ret == 0);

// Check the error status for the read and write operations for the second time

ret = aio_error(&my_aiocb1);

assert (ret == EINPROGRESS);

printf("Second read operation request is suddenly marked as \"in progress\"\n");

ret = aio_error(&my_aiocb2);

assert (ret == 0);

// Get the return code for the write

{

ssize_t retcode = aio_return(&my_aiocb2);

printf("Write operation has completed with results: aio_error=%d, aio_return=%d\n", ret, retcode);

}

// Now try waiting for the read operation to complete - it'll just busy-wait, receiving "EWOULDBLOCK" indefinitely

do

{

printf("\naio_suspend round #%d:\n", nRound++);

ret = aio_suspend( cblist, 1, NULL );

assert (ret == 0);

// Check the error of the read operation and re-issue if needed

ret = aio_error(&my_aiocb1);

if (ret == EWOULDBLOCK)

{

IssueReadOperation(&my_aiocb1, pBuffer);

printf("EWOULDBLOCK again on the read operation!\n");

}

}

while (ret == EWOULDBLOCK);

}

提前致謝,

Yotam.

解決方法:

首先,O_NONBLOCK和AIO不混合.當相應的讀或寫不會被阻塞時,AIO將報告異步操作完成 – 并且使用O_NONBLOCK,它們永遠不會阻塞,因此aio請求將始終立即完成(使用aio_return()給出EWOULDBLOCK).

其次,不要為兩個同時發生的未完成的aio請求使用相同的緩沖區.在發出aio請求的時間和aio_error()告訴你已完成的時間之間,緩沖區應被視為完全禁止.

第三,AIO對同一文件描述符的請求排隊,以便給出明智的結果.這意味著在讀取完成之前不會發生寫入 – 如果您需要先寫入數據,則需要以相反的順序發出AIO.以下工作正常,無需設置O_NONBLOCK:

struct aiocb my_aiocb1, my_aiocb2;

char pBuffer1[BUFSIZE+1], pBuffer2[BUFSIZE+1] = "Some test message";

const struct aiocb *cblist[2] = { &my_aiocb1, &my_aiocb2 };

// Start the read and write operations on the same socket

IssueWriteOperation(&my_aiocb2, pBuffer2);

IssueReadOperation(&my_aiocb1, pBuffer1);

// Wait for I/O completion on both operations

int nRound = 1;

int aio_status1, aio_status2;

do {

printf("\naio_suspend round #%d:\n", nRound++);

ret = aio_suspend( cblist, 2, NULL );

assert (ret == 0);

// Check the error status for the read and write operations

aio_status1 = aio_error(&my_aiocb1);

if (aio_status1 == EINPROGRESS)

puts("aio1 still in progress.");

else

puts("aio1 completed.");

aio_status2 = aio_error(&my_aiocb2);

if (aio_status2 == EINPROGRESS)

puts("aio2 still in progress.");

else

puts("aio2 completed.");

} while (aio_status1 == EINPROGRESS || aio_status2 == EINPROGRESS);

// Get the return code for the read

ssize_t retcode;

retcode = aio_return(&my_aiocb1);

printf("First operation results: aio_error=%d, aio_return=%d\n", aio_status1, retcode);

retcode = aio_return(&my_aiocb1);

printf("Second operation results: aio_error=%d, aio_return=%d\n", aio_status1, retcode);

或者,如果您不關心相互之間的讀取和寫入,您可以使用dup()為套接字創建兩個文件描述符,并使用一個用于讀取而另一個用于寫入 – 每個都將具有AIO操作單獨排隊.

標簽:linux,sockets,kernel,nonblocking,aio

來源: https://codeday.me/bug/20190630/1340573.html

總結

以上是生活随笔為你收集整理的linux 全双工 wifi热点,Linux中的同时套接字读/写(“全双工”)(特别是aio)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。