最近在抓一些基础,所以偶尔也会写一些实例程序,可能写的有点糙,所以拿上来大伙品评品评。
服务端代码:
#include
#include
#include
#pragma comment(lib,"ws2_32")
#define PORT 5150
#define DATA_BUFSIZE 8192
typedef struct _SOCKET_INFORMATION {
OVERLAPPED Overlapped;
SOCKET Socket;
CHAR Buffer[DATA_BUFSIZE];
WSABUF DataBuf;
DWORD BytesSEND;
DWORD BytesRECV;
} SOCKET_INFORMATION, *LPSOCKET_INFORMATION;
void CALLBACK WorkerRoutine(DWORD Error, DWORD BytesTransferred, LPWSAOVERLAPPED Overlapped, DWORD InFlags);
DWORD WINAPI WorkerThread(LPVOID lpParameter);
SOCKET AcceptSocket;
int main(int argc, char **argv)
{
WSADATA wsaData;
SOCKET ListenSocket;
SOCKADDR_IN InternetAddr;
INT Ret;
HANDLE ThreadHandle;
DWORD ThreadId;
WSAEVENT AcceptEvent;
if ((Ret = WSAStartup((2, 2), &wsaData)) != 0)
{
printf("WSAStartup() failed with error %d\n", Ret);
WSACleanup();
return 1;
}
else
printf("WSAStartup() is OK!\n");
if ((ListenSocket = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET)
{
printf("Failed to get a socket %d\n", WSAGetLastError());
return 1;
}
else
printf("WSASocket() is pretty fine!\n");
InternetAddr.sin_family = AF_INET;
InternetAddr.sin_addr.s_addr = htonl(INADDR_ANY);
InternetAddr.sin_port = htons(PORT);
if (bind(ListenSocket, (PSOCKADDR)&InternetAddr, sizeof(InternetAddr)) == SOCKET_ERROR)
{
printf("bind() failed with error %d\n", WSAGetLastError());
return 1;
}
else
printf("bind() is OK!\n");
if (listen(ListenSocket, 5))
{
printf("listen() failed with error %d\n", WSAGetLastError());
return 1;
}
else
printf("listen() is OK!\n");
if ((AcceptEvent = WSACreateEvent()) == WSA_INVALID_EVENT)
{
printf("WSACreateEvent() failed with error %d\n", WSAGetLastError());
return 1;
}
else
printf("WSACreateEvent() is OK!\n");
// Create a worker thread to service completed I/O requests
if ((ThreadHandle = CreateThread(NULL, 0, WorkerThread, (LPVOID)AcceptEvent, 0, &ThreadId)) == NULL)
{
printf("CreateThread() failed with error %d\n", GetLastError());
return 1;
}
else
printf("CreateThread() should be fine!\n");
while (TRUE)
{
AcceptSocket = accept(ListenSocket, NULL, NULL);
if (WSASetEvent(AcceptEvent) == FALSE)
{
printf("WSASetEvent() failed with error %d\n", WSAGetLastError());
return 1;
}
else
printf("WSASetEvent() should be working!\n");
}
}
DWORD WINAPI WorkerThread(LPVOID lpParameter)
{
DWORD Flags;
LPSOCKET_INFORMATION SocketInfo;
WSAEVENT EventArray[1];
DWORD Index;
DWORD RecvBytes;
// Save the accept event in the event array
EventArray[0] = (WSAEVENT)lpParameter;
while (TRUE)
{
// Wait for accept() to signal an event and also process WorkerRoutine() returns
while (TRUE)
{
Index = WSAWaitForMultipleEvents(1, EventArray, FALSE, WSA_INFINITE, TRUE);
if (Index == WSA_WAIT_FAILED)
{
printf("WSAWaitForMultipleEvents() failed with error %d\n", WSAGetLastError());
return FALSE;
}
else
printf("WSAWaitForMultipleEvents() should be OK!\n");
if (Index != WAIT_IO_COMPLETION)
{
// An accept() call event is ready - break the wait loop
break;
}
}
WSAResetEvent(EventArray[Index - WSA_WAIT_EVENT_0]);
// Create a socket information structure to associate with the accepted socket
if ((SocketInfo = (LPSOCKET_INFORMATION)GlobalAlloc(GPTR, sizeof(SOCKET_INFORMATION))) == NULL)
{
printf("GlobalAlloc() failed with error %d\n", GetLastError());
return FALSE;
}
else
printf("GlobalAlloc() for SOCKET_INFORMATION is OK!\n");
// Fill in the details of our accepted socket
SocketInfo->Socket = AcceptSocket;
ZeroMemory(&(SocketInfo->Overlapped), sizeof(WSAOVERLAPPED));
SocketInfo->BytesSEND = 0;
SocketInfo->BytesRECV = 0;
SocketInfo->DataBuf.len = DATA_BUFSIZE;
SocketInfo->DataBuf.buf = SocketInfo->Buffer;
Flags = 0;
if (WSARecv(SocketInfo->Socket, &(SocketInfo->DataBuf), 1, &RecvBytes, &Flags,
&(SocketInfo->Overlapped), WorkerRoutine) == SOCKET_ERROR)
{
if (WSAGetLastError() != WSA_IO_PENDING)
{
printf("WSARecv() failed with error %d\n", WSAGetLastError());
return FALSE;
}
}
else
printf("recv socket s %d ,WSARecv() is OK! the recv is %s\n",SocketInfo->Socket,SocketInfo->DataBuf.buf);
printf("Socket %d got connected...\n", AcceptSocket);
}
return TRUE;
}
void CALLBACK WorkerRoutine(DWORD Error, DWORD BytesTransferred, LPWSAOVERLAPPED Overlapped, DWORD InFlags)
{
DWORD SendBytes, RecvBytes;
DWORD Flags;
// Reference the WSAOVERLAPPED structure as a SOCKET_INFORMATION structure
LPSOCKET_INFORMATION SI = (LPSOCKET_INFORMATION)Overlapped;
if (Error != 0)
{
printf("I/O operation failed with error %d\n", Error);
}
if (BytesTransferred == 0)
{
printf("Closing socket %d\n\n", SI->Socket);
}
if (Error != 0 || BytesTransferred == 0)
{
closesocket(SI->Socket);
GlobalFree(SI);
return;
}
// Check to see if the BytesRECV field equals zero. If this is so, then
// this means a WSARecv call just completed so update the BytesRECV field
// with the BytesTransferred value from the completed WSARecv() call
if (SI->BytesRECV == 0)
{
SI->BytesRECV = BytesTransferred;
SI->BytesSEND = 0;
}
else
{
SI->BytesSEND += BytesTransferred;
}
if (SI->BytesRECV > SI->BytesSEND)
{
ZeroMemory(&(SI->Overlapped), sizeof(WSAOVERLAPPED));
SI->DataBuf.buf = SI->Buffer + SI->BytesSEND;
SI->DataBuf.len = SI->BytesRECV - SI->BytesSEND;
if (WSASend(SI->Socket, &(SI->DataBuf), 1, &SendBytes, 0, &(SI->Overlapped), WorkerRoutine) == SOCKET_ERROR)
{
if (WSAGetLastError() != WSA_IO_PENDING)
{
printf("WSASend() failed with error %d\n", WSAGetLastError());
return;
}
}
else
printf("to say socket s %d, WSASend() is OK! the send buffer is %s\n",SI->Socket,SI->DataBuf.buf);
}
else
{
SI->BytesRECV = 0;
Flags = 0;
ZeroMemory(&(SI->Overlapped), sizeof(WSAOVERLAPPED));
SI->DataBuf.len = DATA_BUFSIZE;
SI->DataBuf.buf = SI->Buffer;
if (WSARecv(SI->Socket, &(SI->DataBuf), 1, &RecvBytes, &Flags, &(SI->Overlapped), WorkerRoutine) == SOCKET_ERROR)
{
if (WSAGetLastError() != WSA_IO_PENDING)
{
printf("WSARecv() failed with error %d\n", WSAGetLastError());
return;
}
}
else
printf("WSARecv() is fine!\n");
}
}
客户端代码:
#include
#include
#include
#ifdef WIN32
#include
#include
#include
#pragma comment(lib, "ws2_32")
#endif
#define TEST_BUFFER "Hello World"
int main(int argc, char** argv) {
#ifdef WIN32
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(2, 2);
err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0) {
return -1;
}
#endif
int s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (s == INVALID_SOCKET) {
return -1;
}
struct sockaddr_in sockaddr;
inet_pton(AF_INET, "127.0.0.1", &sockaddr.sin_addr.S_un.S_addr);
sockaddr.sin_family = AF_INET;
sockaddr.sin_port = htons(5150);
int ret = connect(s, ((struct sockaddr*) &sockaddr), sizeof(sockaddr));
if (ret != 0) {
printf("connect error\n");
closesocket(s);
system("pause");
goto out;
return -1;
}
printf("connect success\n");
char buffer[1024] = { 0 };
memcpy(buffer, TEST_BUFFER, 1024);
printf("socket s %d send buffer is %s\n", s,buffer);
ret = send(s, buffer, 1024, 0);
int iCount = 0;
while (ret > 0 && iCount < 10)
{
memset(buffer, 0, 1024);
ret = recv(s, buffer, 1024, 0);
printf("socket s %d recv buffer is %s\n", s,buffer);
send(s, buffer, 1024, 0);
iCount++;
}
system("pause");
closesocket(s);
out:
#ifdef WIN32
WSACleanup();
#endif
return 0;
}
哈,权且记录下,持续学习中。