Example code of the port completed by beginners

Source: Internet
Author: User
Tags socket error

//////////////////////////////////////// //////////////////////////////////
// Complete the port
//
//
//////////////////////////////////////// //////////////////////////////////

# Include "stdafx. H"
# Include <windows. h>
# Include <winsock2.h>
# Include <stdio. h>

Int initsock ();
DWORD winapi serworkthread (lpvoid completionport );

// Perhandledata
Typedef struct _ per_handle_data
{
Socket socket;
Sockaddr_in clientaddr;
} Per_handle_data, * lpper_handle_data;

// Per Io operation data
Typedef struct _ per_io_operation_data
{
Overlapped;
Wsabuf databuf;
Char buffer [8192];
DWORD bytessend;
DWORD bytesrecv;
} Per_io_operation_data, * lpper_io_operation_data;

Int main (INT argc, char * argv [])
{
Handle hcompletionport;
System_info sysinfo;
Int I = 0;
Socket listen;
Socket accept;
Sockaddr_in inetaddr;
DWORD flags = 0;
DWORD recvbytes = 0;
Sockaddr_in saremote;
Int saremotelen = sizeof (saremote );
Lpper_handle_data perhandledata = NULL;
Lpper_io_operation_data periooperationdata = NULL;
 
If (! Initsock ()){
Printf ("initsock error! /N ");
Return 0;
}
// The created port
Hcompletionport = createiocompletionport (invalid_handle_value, null, 0, 0 );
If (hcompletionport = NULL ){
Printf ("creatae completionport Error !! /N ");
Return 0;
}
 
// Create a worker thread. The number of threads is consistent with the number of CPUs.
// The worker thread provides services for port completion when the IO request arrives.
Getsysteminfo (& sysinfo );
For (I = 0; I <(INT) sysinfo. dwnumberofprocessors; I ++)
{
Handle hthread;
Hthread = createthread (null, 0, serworkthread, hcompletionport, 0, null );
If (hthread = NULL ){
Printf ("createthread fail! ");
}
Closehandle (hthread );
}
 
// Note that the socket here is TCP
Listen = wsasocket (af_inet, sock_stream, 0, null, 0, wsa_flag_overlapped );
If (Listen = invalid_socket ){
Printf ("Listen's socket error! /N ");
Return 0;
}
Inetaddr. sin_family = af_inet;
Inetaddr. sin_port = htons (5010 );
Inetaddr. sin_addr.s_un.s_addr = htonl (inaddr_any );
 
If (BIND (Listen, (sockaddr *) & inetaddr,
Sizeof (sockaddr) = socket_error ){
Printf ("BIND error/N ");
Return 0;
}
If (Listen, 5) = socket_error) {// note the second parameter
Printf ("Listen error/N ");
Return 0;
}
 
While (true)
{
Accept = wsaaccept (Listen, (sockaddr *) & saremote, & saremotelen, null, null );
If (accept = socket_error ){
Printf ("Accept error/N ");
}
// Set per-handle data
Perhandledata = (lpper_handle_data) globalalloc (gptr, sizeof (per_handle_data ));
If (perhandledata = NULL ){
Printf ("globalalloc momery error! ");
Return 0;
}
Printf ("socket Number % d connected./N", accept );
Perhandledata-> socket = accept;
Memcpy (& perhandledata-> clientaddr, & saremote, saremotelen );
// Perhandledata contains other socket-related information
If (createiocompletionport (handle) Accept, hcompletionport, (DWORD) perhandledata, 0) = NULL ){
Printf ("createcompletionport error! ");
Return 0;
}

Periooperationdata = (lpper_io_operation_data) globalalloc (
Gptr, sizeof (per_io_operation_data ));
Zeromemory (& (periooperationdata-> overlapped), sizeof (overlapped ));
Periooperationdata-> bytessend = 0;
Periooperationdata-> bytesrecv = 0;
Periooperationdata-> databuf. Buf = periooperationdata-> buffer;
Periooperationdata-> databuf. Len = 8192;

Flags = 0;
If (wsarecv (accept, & (periooperationdata-> databuf), 1, & recvbytes, & flags,
& (Periooperationdata-> overlapped), null) = socket_error ){

If (wsagetlasterror ()! = Error_io_pending)
{
Printf ("wsarecv () failed with error % d/N", wsagetlasterror ());
Return;
}
}
}
}

Int initsock (void)
{
Word wversionrequested;
Wsadata;
Int err;
 
Wversionrequested = makeword (2, 2 );
 
Err = wsastartup (wversionrequested, & wsadata );
If (Err! = 0 ){
Return 0;
}
If (lobyte (wsadata. wversion )! = 2 |
Hibyte (wsadata. wversion )! = 2 ){
Wsacleanup ();
Return 0;
}
Return 1;
}

DWORD winapi serworkthread (lpvoid completionportid)
{
Handle completionport = (handle) completionportid;
DWORD bytestransferred;
// Lpoverlapped overlapped;
Lpper_handle_data perhandledata;
Lpper_io_operation_data periodata;
DWORD sendbytes, recvbytes;
DWORD flags;
 
While (true)
{
// Obtain the status of the completed port queue. Here, the information after I/O operations is passed into perhandledata and periodata.
If (getqueuedcompletionstatus (completionport, & bytestransferred,
(Lpdword) & perhandledata, (lpoverlapped *) & periodata, infinite) = 0)
{
Printf ("getqueuedcompletionstatus failed with error % d/N", getlasterror ());
Return 0;
}

// Bytestransferred the actual number of characters received/transmitted after an IO operation is completed
If (bytestransferred = 0) // The data has been sent
{
Printf ("Closing socket % d/N", perhandledata-> socket );
If (closesocket (perhandledata-> socket) = socket_error)
{
Printf ("closesocket () failed with error % d/N", wsagetlasterror ());
Return 0;
}
Globalfree (perhandledata );
Globalfree (periodata );
Continue;
}

If (periodata-> bytesrecv = 0)
{
Periodata-> bytesrecv = bytestransferred;
Periodata-> bytessend = 0;
}
Else
{
Periodata-> bytessend + = bytestransferred;
}

If (periodata-> bytesrecv> periodata-> bytessend)
{
Zeromemory (& (periodata-> overlapped), sizeof (overlapped ));

Periodata-> databuf. Buf = periodata-> buffer + periodata-> bytessend;
Periodata-> databuf. Len = periodata-> bytesrecv-periodata-> bytessend;

If (wsasend (perhandledata-> socket, & (periodata-> databuf), 1, & sendbytes, 0,
& (Periodata-> overlapped), null) = socket_error)
{
If (wsagetlasterror ()! = Error_io_pending)
{
Printf ("wsasend () failed with error % d/N", wsagetlasterror ());
Return 0;
}
}
}
Else
{
Periodata-> bytesrecv = 0;
Flags = 0;
Zeromemory (& (periodata-> overlapped), sizeof (overlapped ));
Periodata-> databuf. Len = 8192;
Periodata-> databuf. Buf = periodata-> buffer;
If (wsarecv (perhandledata-> socket, & (periodata-> databuf), 1, & recvbytes, & flags,
& (Periodata-> overlapped), null) = socket_error)
{
If (wsagetlasterror ()! = Error_io_pending)
{
Printf ("wsarecv () failed with error % d/N", wsagetlasterror ());
Return 0;
}
}
Else
{// Print the received message
Printf ("% s", & periodata-> databuf );
}
}
}
}
 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.