服务器端的大体代码.代码是我做测试是使用.结构不好.
#define PORT 1130
#define MAXSIZE 1024
#define null NULL
struct OVERPROT
{
int xvier;
OVERLAPPED Overlapped;
WSABUF DataBuf; // 接收数据的缓冲区
CHAR Buffer[MAXSIZE];
DWORD BytesSEND; // 发送字节数
DWORD BytesRECV; // 接收的字节数.
SOCKET server; // 服务器的socket;
SOCKET client; // 客户端的socket;
};
SOCKET *wparam = null;
OVERPROT *overprot = null;
DWORD WINAPI ServerWorkerThread(LPVOID CompletionPortID);
int _tmain(int argc, _TCHAR* argv[])
{
WSADATA wsaData;
if(::WSAStartup(MAKEWORD(2,2),&wsaData) !=0)
{
cout<<"WSAStratup function exception!"<<endl;
return -1;
}
HANDLE completionport = ::CreateIoCompletionPort(INVALID_HANDLE_VALUE,0,0,0);
if(completionport == NULL)
{
cout<<"CreateIoCompletionPort function exception"<<endl;
goto Exit;
}
SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
if(sock == SOCKET_ERROR)
{
cout<<"socket function exception"<<endl;
goto Exit;
}
DWORD dword=0;
HANDLE thread =::CreateThread(NULL,0,ServerWorkerThread,completionport,0,&dword);
if(thread == null)
{
cout<<"CreateThread function exception"<<endl;
goto Exit;
}
SOCKADDR_IN sockaddr;
sockaddr.sin_family = AF_INET;
sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
sockaddr.sin_port = htons(PORT);
if(::bind(sock,(PSOCKADDR)&sockaddr,sizeof(sockaddr)) == SOCKET_ERROR)
{
cout<<"bind function exception"<<endl;
goto Exit;
}
if(::listen(sock,50) == SOCKET_ERROR)
{
cout<<"listen function exception"<<endl;
goto Exit;
}
while(TRUE)
{
SOCKET client = ::WSAAccept(sock,NULL,NULL,NULL,0);
if(client == SOCKET_ERROR)
{
cout<<"Accept function exception"<<endl;
goto Exit;
}
overprot = (OVERPROT *)::GlobalAlloc(GPTR,sizeof(OVERPROT));
if(overprot == null)
{
cout<<"GlobalAlloc OVERPTOR function exception"<<endl;
goto Exit;
}
memset(&overprot->Overlapped,0,sizeof(OVERLAPPED));
overprot->BytesRECV = 0;
overprot->BytesSEND = 0;
overprot->DataBuf.buf = overprot->Buffer;
overprot->DataBuf.len = MAXSIZE;
overprot->server = sock;
overprot->client = client;
if(::CreateIoCompletionPort((HANDLE)client,completionport,(DWORD)overprot,0) == NULL)
{
cout<<"CreateIocompletionPort function bind socket excetion"<<endl;
goto Exit;
}
DWORD RecvBytes,flast=0;
// 这次接收是正常的.
if (WSARecv(client, &(overprot->DataBuf), 1, &RecvBytes, &flast,
&(overprot->Overlapped), NULL) == SOCKET_ERROR)
{
if (WSAGetLastError() != ERROR_IO_PENDING)
{
printf("WSARecv() failed with error %d\n", WSAGetLastError());
goto Exit;
}
}
}
Exit:
if(overprot != NULL) ::GlobalFree(overprot);
if(thread != NULL) ::CloseHandle(thread);
if(sock != SOCKET_ERROR) ::closesocket(sock);
if(completionport != NULL) ::CloseHandle(completionport);
::WSACleanup();
return 0;
}
DWORD WINAPI ServerWorkerThread(LPVOID CompletionPortID)
{
HANDLE CompletionPort = (HANDLE) CompletionPortID;
DWORD dwBytesXfered;
LONG_PTR PerHandleKey;
OVERPROT *overlap ;
DWORD RecvBytes,flast=0;
while(true)
{
int ret = GetQueuedCompletionStatus(
CompletionPort,
&dwBytesXfered,
(PULONG_PTR)&PerHandleKey,
(LPOVERLAPPED *)&overlap,
INFINITE);
if (ret == 0)
{
continue;
}
// 第一次接收是能取得数据的.
// cout<<"Data length"<< dwBytesXfered<<endl;
// cout<<"DataBuffer "<<overlap->Buffer<<endl;
// cout<<"Recv length "<<overlap->BytesRECV <<endl;
// cout<<"Send length "<<overlap->BytesSEND<<endl;
memset(&(overlap->Overlapped),0,sizeof(OVERLAPPED));
overprot->BytesRECV = 0;
overprot->BytesSEND = 0;
overprot->DataBuf.buf = overprot->Buffer;
overprot->DataBuf.len = MAXSIZE;
// 但在这次接收的时候,确报10038 . 在主线程中也是用了这个 client socket了.但又没错
if (WSARecv(overlap->client, &(overprot->DataBuf), 1, &RecvBytes, &flast,
&(overprot->Overlapped), NULL) == SOCKET_ERROR)
{
if (WSAGetLastError() != ERROR_IO_PENDING)
{
printf("WSARecv() failed with error %d\n", WSAGetLastError());
}
}
}
return 0;
}
客户端很简单只是发送字符串,用C#写的.代码如下:
static void Main(string[] args)
{
IPHostEntry localhost = Dns.GetHostEntry(Dns.GetHostName());
IPEndPoint ipend = new IPEndPoint(localhost.AddressList[0].Address, 1130);
int sendcount = 99;
byte[] bytebuffer = new byte[1024];
Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
client.Connect(ipend);
while ((sendcount--)>0)
{
string strbuffer = "Hello world! Say time:" + DateTime.Now.ToString();
bytebuffer = Encoding.ASCII.GetBytes(strbuffer);
int v=client.Send(bytebuffer);
Console.Write("Send Count {0} \n {1}", sendcount, strbuffer);
Thread.Sleep(99);
}
client.Shutdown(SocketShutdown.Both);
client.Close();
Console.Read();
}
6 个解决方案
#1
没找到ClientSocket
#2
可以 Client Socket 我在主线程中加进去了啊.
overprot = (OVERPROT *)::GlobalAlloc(GPTR,sizeof(OVERPROT));
if(overprot == null)
{
cout<<"GlobalAlloc OVERPTOR function exception"<<endl;
goto Exit;
}
memset(&overprot->Overlapped,0,sizeof(OVERLAPPED));
overprot->BytesRECV = 0;
overprot->BytesSEND = 0;
overprot->DataBuf.buf = overprot->Buffer;
overprot->DataBuf.len = MAXSIZE;
overprot->server = sock;
overprot->client = client;
if(::CreateIoCompletionPort((HANDLE)client,completionport,(DWORD)overprot,0) == NULL)
{
cout<<"CreateIocompletionPort function bind socket excetion"<<endl;
goto Exit;
}
在线程中.的WSARecv 函数中我下了断点.看到client socket 并不为 0 啊.
overprot = (OVERPROT *)::GlobalAlloc(GPTR,sizeof(OVERPROT));
if(overprot == null)
{
cout<<"GlobalAlloc OVERPTOR function exception"<<endl;
goto Exit;
}
memset(&overprot->Overlapped,0,sizeof(OVERLAPPED));
overprot->BytesRECV = 0;
overprot->BytesSEND = 0;
overprot->DataBuf.buf = overprot->Buffer;
overprot->DataBuf.len = MAXSIZE;
overprot->server = sock;
overprot->client = client;
if(::CreateIoCompletionPort((HANDLE)client,completionport,(DWORD)overprot,0) == NULL)
{
cout<<"CreateIocompletionPort function bind socket excetion"<<endl;
goto Exit;
}
在线程中.的WSARecv 函数中我下了断点.看到client socket 并不为 0 啊.
#3
楼主,严谨些
但在接收第二次的时候出现10038.说ClientSocket 不是套接字
但在接收第二次的时候出现10038.说ClientSocket 不是套接字
#4
while(TRUE)
{
SOCKET client = ::WSAAccept(sock,NULL,NULL,NULL,0);
if(client == SOCKET_ERROR)
{
cout<<"Accept function exception"<<endl;
goto Exit;
}
overprot = (OVERPROT *)::GlobalAlloc(GPTR,sizeof(OVERPROT));
if(overprot == null)
{
cout<<"GlobalAlloc OVERPTOR function exception"<<endl;
goto Exit;
}
memset(&overprot->Overlapped,0,sizeof(OVERLAPPED));
overprot->BytesRECV = 0;
overprot->BytesSEND = 0;
overprot->DataBuf.buf = overprot->Buffer;
overprot->DataBuf.len = MAXSIZE;
overprot->server = sock;
overprot->client = client;
if(::CreateIoCompletionPort((HANDLE)client,completionport,(DWORD)overprot,0) == NULL)
{
cout<<"CreateIocompletionPort function bind socket excetion"<<endl;
goto Exit;
}
DWORD RecvBytes,flast=0;
// 这次接收是正常的.
if (WSARecv(client, &(overprot->DataBuf), 1, &RecvBytes, &flast,
&(overprot->Overlapped), NULL) == SOCKET_ERROR)
{
if (WSAGetLastError() != ERROR_IO_PENDING)
{
printf("WSARecv() failed with error %d\n", WSAGetLastError());
goto Exit;
}
}
}
在第二次进去循环时,client已经变了啊
{
SOCKET client = ::WSAAccept(sock,NULL,NULL,NULL,0);
if(client == SOCKET_ERROR)
{
cout<<"Accept function exception"<<endl;
goto Exit;
}
overprot = (OVERPROT *)::GlobalAlloc(GPTR,sizeof(OVERPROT));
if(overprot == null)
{
cout<<"GlobalAlloc OVERPTOR function exception"<<endl;
goto Exit;
}
memset(&overprot->Overlapped,0,sizeof(OVERLAPPED));
overprot->BytesRECV = 0;
overprot->BytesSEND = 0;
overprot->DataBuf.buf = overprot->Buffer;
overprot->DataBuf.len = MAXSIZE;
overprot->server = sock;
overprot->client = client;
if(::CreateIoCompletionPort((HANDLE)client,completionport,(DWORD)overprot,0) == NULL)
{
cout<<"CreateIocompletionPort function bind socket excetion"<<endl;
goto Exit;
}
DWORD RecvBytes,flast=0;
// 这次接收是正常的.
if (WSARecv(client, &(overprot->DataBuf), 1, &RecvBytes, &flast,
&(overprot->Overlapped), NULL) == SOCKET_ERROR)
{
if (WSAGetLastError() != ERROR_IO_PENDING)
{
printf("WSARecv() failed with error %d\n", WSAGetLastError());
goto Exit;
}
}
}
在第二次进去循环时,client已经变了啊
#5
......谢谢.ouyh12345. 我闷了.....我知道错在那里了.谢谢....深刻的教训.
#6
为什么client在进第二次循环的时候就变了呢????
#1
没找到ClientSocket
#2
可以 Client Socket 我在主线程中加进去了啊.
overprot = (OVERPROT *)::GlobalAlloc(GPTR,sizeof(OVERPROT));
if(overprot == null)
{
cout<<"GlobalAlloc OVERPTOR function exception"<<endl;
goto Exit;
}
memset(&overprot->Overlapped,0,sizeof(OVERLAPPED));
overprot->BytesRECV = 0;
overprot->BytesSEND = 0;
overprot->DataBuf.buf = overprot->Buffer;
overprot->DataBuf.len = MAXSIZE;
overprot->server = sock;
overprot->client = client;
if(::CreateIoCompletionPort((HANDLE)client,completionport,(DWORD)overprot,0) == NULL)
{
cout<<"CreateIocompletionPort function bind socket excetion"<<endl;
goto Exit;
}
在线程中.的WSARecv 函数中我下了断点.看到client socket 并不为 0 啊.
overprot = (OVERPROT *)::GlobalAlloc(GPTR,sizeof(OVERPROT));
if(overprot == null)
{
cout<<"GlobalAlloc OVERPTOR function exception"<<endl;
goto Exit;
}
memset(&overprot->Overlapped,0,sizeof(OVERLAPPED));
overprot->BytesRECV = 0;
overprot->BytesSEND = 0;
overprot->DataBuf.buf = overprot->Buffer;
overprot->DataBuf.len = MAXSIZE;
overprot->server = sock;
overprot->client = client;
if(::CreateIoCompletionPort((HANDLE)client,completionport,(DWORD)overprot,0) == NULL)
{
cout<<"CreateIocompletionPort function bind socket excetion"<<endl;
goto Exit;
}
在线程中.的WSARecv 函数中我下了断点.看到client socket 并不为 0 啊.
#3
楼主,严谨些
但在接收第二次的时候出现10038.说ClientSocket 不是套接字
但在接收第二次的时候出现10038.说ClientSocket 不是套接字
#4
while(TRUE)
{
SOCKET client = ::WSAAccept(sock,NULL,NULL,NULL,0);
if(client == SOCKET_ERROR)
{
cout<<"Accept function exception"<<endl;
goto Exit;
}
overprot = (OVERPROT *)::GlobalAlloc(GPTR,sizeof(OVERPROT));
if(overprot == null)
{
cout<<"GlobalAlloc OVERPTOR function exception"<<endl;
goto Exit;
}
memset(&overprot->Overlapped,0,sizeof(OVERLAPPED));
overprot->BytesRECV = 0;
overprot->BytesSEND = 0;
overprot->DataBuf.buf = overprot->Buffer;
overprot->DataBuf.len = MAXSIZE;
overprot->server = sock;
overprot->client = client;
if(::CreateIoCompletionPort((HANDLE)client,completionport,(DWORD)overprot,0) == NULL)
{
cout<<"CreateIocompletionPort function bind socket excetion"<<endl;
goto Exit;
}
DWORD RecvBytes,flast=0;
// 这次接收是正常的.
if (WSARecv(client, &(overprot->DataBuf), 1, &RecvBytes, &flast,
&(overprot->Overlapped), NULL) == SOCKET_ERROR)
{
if (WSAGetLastError() != ERROR_IO_PENDING)
{
printf("WSARecv() failed with error %d\n", WSAGetLastError());
goto Exit;
}
}
}
在第二次进去循环时,client已经变了啊
{
SOCKET client = ::WSAAccept(sock,NULL,NULL,NULL,0);
if(client == SOCKET_ERROR)
{
cout<<"Accept function exception"<<endl;
goto Exit;
}
overprot = (OVERPROT *)::GlobalAlloc(GPTR,sizeof(OVERPROT));
if(overprot == null)
{
cout<<"GlobalAlloc OVERPTOR function exception"<<endl;
goto Exit;
}
memset(&overprot->Overlapped,0,sizeof(OVERLAPPED));
overprot->BytesRECV = 0;
overprot->BytesSEND = 0;
overprot->DataBuf.buf = overprot->Buffer;
overprot->DataBuf.len = MAXSIZE;
overprot->server = sock;
overprot->client = client;
if(::CreateIoCompletionPort((HANDLE)client,completionport,(DWORD)overprot,0) == NULL)
{
cout<<"CreateIocompletionPort function bind socket excetion"<<endl;
goto Exit;
}
DWORD RecvBytes,flast=0;
// 这次接收是正常的.
if (WSARecv(client, &(overprot->DataBuf), 1, &RecvBytes, &flast,
&(overprot->Overlapped), NULL) == SOCKET_ERROR)
{
if (WSAGetLastError() != ERROR_IO_PENDING)
{
printf("WSARecv() failed with error %d\n", WSAGetLastError());
goto Exit;
}
}
}
在第二次进去循环时,client已经变了啊
#5
......谢谢.ouyh12345. 我闷了.....我知道错在那里了.谢谢....深刻的教训.
#6
为什么client在进第二次循环的时候就变了呢????