社区
网络编程
帖子详情
不用多线程,如何处理多个socket
cyberkit
2005-11-11 07:52:04
很多代码都是用多线程处理多个socket,虽然很方便,但是如果socket很多,多线程必然会使效率降低
如果不用多线程该怎么做,windows网络编程里的代码过于省略,请各位贴几个完整的代码看看好吗?谢谢
...全文
402
13
打赏
收藏
不用多线程,如何处理多个socket
很多代码都是用多线程处理多个socket,虽然很方便,但是如果socket很多,多线程必然会使效率降低 如果不用多线程该怎么做,windows网络编程里的代码过于省略,请各位贴几个完整的代码看看好吗?谢谢
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
13 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
winnuke
2005-11-26
打赏
举报
回复
选择一下io模型..
kugou123
2005-11-25
打赏
举报
回复
用Select I/O ,一个线程默认可以管理64个连接。
freemme
2005-11-25
打赏
举报
回复
如果要实现效率比较高的服务器,用完成端口是最好的,由操作系统帮你管理数据的io工作。
ghost8367
2005-11-24
打赏
举报
回复
套接字设置成非阻塞的,用select轮寻的接受.
xxbtop
2005-11-17
打赏
举报
回复
实际上一个server.cpp和一个client.cpp就可以实现简单的socket通信
xiangding
2005-11-15
打赏
举报
回复
代码不错,但是太长
hejie19q2004
2005-11-14
打赏
举报
回复
else // No error so update the byte count
{
SocketInfo->BytesSEND += SendBytes;
}
}
if (SocketInfo->BytesSEND == SocketInfo->BytesRECV)
{
SocketInfo->BytesSEND = 0;
SocketInfo->BytesRECV = 0;
// If a RECV occurred during our SENDs then we need to post an FD_READ
// notification on the socket.
if (SocketInfo->RecvPosted == TRUE)
{
SocketInfo->RecvPosted = FALSE;
PostMessage(hwnd, WM_SOCKET, wParam, FD_READ);
}
}
break;
case FD_CLOSE:
printf("Closing socket %d\n", wParam);
FreeSocketInformation(wParam);
break;
}
}
return 0;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
void CreateSocketInformation(SOCKET s)
{
LPSOCKET_INFORMATION SI;
if ((SI = (LPSOCKET_INFORMATION) GlobalAlloc(GPTR,
sizeof(SOCKET_INFORMATION))) == NULL)
{
printf("GlobalAlloc() failed with error %d\n", GetLastError());
return;
}
// Prepare SocketInfo structure for use.
SI->Socket = s;
SI->RecvPosted = FALSE;
SI->BytesSEND = 0;
SI->BytesRECV = 0;
SI->Next = SocketInfoList;
SocketInfoList = SI;
}
LPSOCKET_INFORMATION GetSocketInformation(SOCKET s)
{
SOCKET_INFORMATION *SI = SocketInfoList;
while(SI)
{
if (SI->Socket == s)
return SI;
SI = SI->Next;
}
return NULL;
}
void FreeSocketInformation(SOCKET s)
{
SOCKET_INFORMATION *SI = SocketInfoList;
SOCKET_INFORMATION *PrevSI = NULL;
while(SI)
{
if (SI->Socket == s)
{
if (PrevSI)
PrevSI->Next = SI->Next;
else
SocketInfoList = SI->Next;
closesocket(SI->Socket);
GlobalFree(SI);
return;
}
PrevSI = SI;
SI = SI->Next;
}
}
HWND MakeWorkerWindow(void)
{
WNDCLASS wndclass;
CHAR *ProviderClass = "AsyncSelect";
HWND Window;
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = (WNDPROC)WindowProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = NULL;
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = ProviderClass;
if (RegisterClass(&wndclass) == 0)
{
printf("RegisterClass() failed with error %d\n", GetLastError());
return NULL;
}
// Create a window.
if ((Window = CreateWindow(
ProviderClass,
"",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
NULL,
NULL)) == NULL)
{
printf("CreateWindow() failed with error %d\n", GetLastError());
return NULL;
}
return Window;
}
hejie19q2004
2005-11-14
打赏
举报
回复
while(Ret = GetMessage(&msg, NULL, 0, 0))
{
if (Ret == -1)
{
printf("GetMessage() failed with error %d\n", GetLastError());
return;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
SOCKET Accept;
LPSOCKET_INFORMATION SocketInfo;
DWORD RecvBytes, SendBytes;
DWORD Flags;
if (uMsg == WM_SOCKET)
{
if (WSAGETSELECTERROR(lParam))
{
printf("Socket failed with error %d\n", WSAGETSELECTERROR(lParam));
FreeSocketInformation(wParam);
}
else
{
switch(WSAGETSELECTEVENT(lParam))
{
case FD_ACCEPT:
if ((Accept = accept(wParam, NULL, NULL)) == INVALID_SOCKET)
{
printf("accept() failed with error %d\n", WSAGetLastError());
break;
}
// Create a socket information structure to associate with the
// socket for processing I/O.
CreateSocketInformation(Accept);
printf("Socket number %d connected\n", Accept);
WSAAsyncSelect(Accept, hwnd, WM_SOCKET, FD_READ|FD_WRITE|FD_CLOSE);
break;
case FD_READ:
SocketInfo = GetSocketInformation(wParam);
// Read data only if the receive buffer is empty.
if (SocketInfo->BytesRECV != 0)
{
SocketInfo->RecvPosted = TRUE;
return 0;
}
else
{
SocketInfo->DataBuf.buf = SocketInfo->Buffer;
SocketInfo->DataBuf.len = DATA_BUFSIZE;
Flags = 0;
if (WSARecv(SocketInfo->Socket, &(SocketInfo->DataBuf), 1, &RecvBytes,
&Flags, NULL, NULL) == SOCKET_ERROR)
{
if (WSAGetLastError() != WSAEWOULDBLOCK)
{
printf("WSARecv() failed with error %d\n", WSAGetLastError());
FreeSocketInformation(wParam);
return 0;
}
}
else // No error so update the byte count
{
SocketInfo->BytesRECV = RecvBytes;
}
}
// DO NOT BREAK HERE SINCE WE GOT A SUCCESSFUL RECV. Go ahead
// and begin writing data to the client.
case FD_WRITE:
SocketInfo = GetSocketInformation(wParam);
if (SocketInfo->BytesRECV > SocketInfo->BytesSEND)
{
SocketInfo->DataBuf.buf = SocketInfo->Buffer + SocketInfo->BytesSEND;
SocketInfo->DataBuf.len = SocketInfo->BytesRECV - SocketInfo->BytesSEND;
if (WSASend(SocketInfo->Socket, &(SocketInfo->DataBuf), 1, &SendBytes, 0,
NULL, NULL) == SOCKET_ERROR)
{
if (WSAGetLastError() != WSAEWOULDBLOCK)
{
printf("WSASend() failed with error %d\n", WSAGetLastError());
FreeSocketInformation(wParam);
return 0;
}
}
hejie19q2004
2005-11-14
打赏
举报
回复
#include <winsock2.h>
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#define PORT 5150
#define DATA_BUFSIZE 8192
typedef struct _SOCKET_INFORMATION {
BOOL RecvPosted;
CHAR Buffer[DATA_BUFSIZE];
WSABUF DataBuf;
SOCKET Socket;
DWORD BytesSEND;
DWORD BytesRECV;
_SOCKET_INFORMATION *Next;
} SOCKET_INFORMATION, * LPSOCKET_INFORMATION;
#define WM_SOCKET (WM_USER + 1)
void CreateSocketInformation(SOCKET s);
LPSOCKET_INFORMATION GetSocketInformation(SOCKET s);
void FreeSocketInformation(SOCKET s);
HWND MakeWorkerWindow(void);
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
LPSOCKET_INFORMATION SocketInfoList;
void main(void)
{
MSG msg;
DWORD Ret;
SOCKET Listen;
SOCKADDR_IN InternetAddr;
HWND Window;
WSADATA wsaData;
if ((Window = MakeWorkerWindow()) == NULL)
return;
// Prepare echo server
if ((Ret = WSAStartup(0x0202, &wsaData)) != 0)
{
printf("WSAStartup failed with error %d\n", Ret);
return;
}
if ((Listen = socket (PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
{
printf("socket() failed with error %d\n", WSAGetLastError());
return;
}
WSAAsyncSelect(Listen, Window, WM_SOCKET, FD_ACCEPT|FD_CLOSE);
InternetAddr.sin_family = AF_INET;
InternetAddr.sin_addr.s_addr = htonl(INADDR_ANY);
InternetAddr.sin_port = htons(PORT);
if (bind(Listen, (PSOCKADDR) &InternetAddr, sizeof(InternetAddr)) == SOCKET_ERROR)
{
printf("bind() failed with error %d\n", WSAGetLastError());
return;
}
if (listen(Listen, 5))
{
printf("listen() failed with error %d\n", WSAGetLastError());
return;
}
// Translate and dispatch window messages for the application thread
贵子潘
2005-11-12
打赏
举报
回复
实质上还是多线程...
nuaawenlin
2005-11-11
打赏
举报
回复
WSAAsyncSelect(),异步选择模式
lifengice0706
2005-11-11
打赏
举报
回复
使用select模式,代码在csdn或google找。
bluekite
2005-11-11
打赏
举报
回复
關注一下!
客户端app多个
线
程对一个
socket
发送数据
客户端一般是一个发送
线
程,一个
socket
多个发送
线
程竞争一个
socket
没什么意义,不会提高发送速度,因为
socket
只有一个,只要
socket
在发送一个
线
程的数据时,该
socket
就被占用了,是不会响应其他
线
程的发送数据请求的。除非客户端维护有多个
socket
。 服务端使用多
线
程向多个客户端同时发送数据是因为服务端维护着多个
socket
,每个
socket
对应一个客户端session连接。 参考: 客户端:多
线
程使用单个
SOCKET
发数 请教:多
线
程使用同一个
socket
进行数据收发会出现什么问题?
Qt
Socket
多
线
程操作
Qt 关于
Socket
多
线
程通信 最近有个项目需要用到Qt中的
socket
通信,于是就查阅网上的一些资料和QT API的文档,过程虽然比较艰难,但成果确实~,你懂得,现在就和大家分享它们的用法. 首先Qt关于关于
Socket
需要使用QTcpServer和QTcp
Socket
,其中QTcpServer做为服务端,而QTcp
Socket
则作为客户端.通过查看QTcpServer的API,它可以通
socket
网络编程——多进程、多
线
程
处理
并发
1.服务器
处理
并发的必要性 如下图所示, 当一个客户端与服务器建立连接以后,服务器端 accept()返回,进而准备循环接收客户端发过来的数据。如果客户端暂时没发数据,服务端会在 recv()处阻塞。此时,其他客户端向服务器发起连接后,由于服务器阻塞了,无法执行 accept()接受连接,也就是其他客户端发送的数据,服务器无法读取。服务器也就无法并发同时
处理
多个客户端。 这个问题可以通过引入多
线
程和多进程来解决。服务端接受一个客户端的连接后,创建一个
线
程或者进程,然后在新创建的
线
程或进程中循环
处理
数据。主
socket
多
线
程
socket
多
线
程
Qt多
线
程
socket
服务器开发
前言 闲话少说,因需要写一个上位机程序,本来我是打算用纯C++开发的,奈何我不是程序员科班出身,对多
线
程+win
socket
那一套不是很熟悉,平时写写简单的测试案例还可以,但是要我写出一个能稳定运行的落地的项目,纯C++开发对我来说太难了。其实Qt我也不是很熟悉,但Qt毕竟大多模块帮你封装好了,适用qt可以大大缩短开发周期。 qt多
线
程 网上关于qt多
线
程的大多都是继承QThread,然后...
网络编程
18,356
社区成员
64,214
社区内容
发帖
与我相关
我的任务
网络编程
VC/MFC 网络编程
复制链接
扫一扫
分享
社区描述
VC/MFC 网络编程
c++
c语言
开发语言
技术论坛(原bbs)
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章