社区
网络编程
帖子详情
不用多线程,如何处理多个socket
cyberkit
2005-11-11 07:52:04
很多代码都是用多线程处理多个socket,虽然很方便,但是如果socket很多,多线程必然会使效率降低
如果不用多线程该怎么做,windows网络编程里的代码过于省略,请各位贴几个完整的代码看看好吗?谢谢
...全文
423
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
打赏
举报
回复
關注一下!
Android基于
Socket
聊天最终版
总的来说,这个项目涵盖了Android应用开发中的
多个
关键知识点,如
Socket
通信、
多线程
、数据库操作和UI设计。开发者通过实现这个项目,不仅掌握了网络编程的基本原理,还锻炼了在Android平台上构建实际应用的能力。
android在wifi下手机与电脑的
socket
通信
为避免阻塞,通常会在单独的线程中执行`accept()`,以便同时
处理
多个
客户端连接。 在提供的文件列表中,"ControlPC"和"Keyexe"可能包含实现这一通信的代码。"ControlPC"可能是一个控制电脑的程序,而"Keyexe"可能是...
同时打开多端口的通信程序
- 为了实现实时并发
处理
多个
客户端请求,程序可能采用
多线程
或者事件驱动模型,每个连接对应一个独立的线程或事件
处理
单元,这样可以在不阻塞主线程的情况下
处理
网络通信。 3. **服务端和客户端架构**: - 服务端...
客户端app
多个
线程对一个
socket
发送数据
服务端使用
多线程
向
多个
客户端同时发送数据是因为服务端维护着
多个
socket
,每个
socket
对应一个客户端session连接。 参考: 客户端:
多线程
使用单个
SOCKET
发数 请教:
多线程
使用同一个
socket
进行数据收发会出现什么...
QT实现高并发
多线程
处理
多个
Socket
客户端
实现
多线程
方法有两种,分别是继承QObject或者继承QThread。本文使用继承QObject,并使用moveToThread将客户端
Socket
移动到线程中执行。主要是为了使得每个客户端进来后,分配一个线程进行
处理
。4. 具体代码结构如下...
网络编程
18,357
社区成员
64,164
社区内容
发帖
与我相关
我的任务
网络编程
VC/MFC 网络编程
复制链接
扫一扫
分享
社区描述
VC/MFC 网络编程
c++
c语言
开发语言
技术论坛(原bbs)
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章