As for Why do Microsoft code samples tend to use ZeroMemory instead of ={ 0 }?
Are there any differences?
You can search it on baidu.
But I recommend to visit a discussion post on msdn: http://blogs.msdn.com/b/oldnewthing/archive/2005/06/28/433341.aspx
Since I find that all the searching results on baidu are slightly different.
However, after having a quick browsing on the discussion post, I get more than I've expected.
Maybe one not well-known feature is as follow:
Sayeth K&R:"Unnamed bit-field members are ignored, and are not initialized."; Zero memory is going to clear all of the bitfields in your struct, but the ={0} technique does not.
Are there any differences?
You can search it on baidu.
But I recommend to visit a discussion post on msdn: http://blogs.msdn.com/b/oldnewthing/archive/2005/06/28/433341.aspx
Since I find that all the searching results on baidu are slightly different.
However, after having a quick browsing on the discussion post, I get more than I've expected.
Maybe one not well-known feature is as follow:
Sayeth K&R:"Unnamed bit-field members are ignored, and are not initialized."; Zero memory is going to clear all of the bitfields in your struct, but the ={0} technique does not.
By the way, do not use ZeroMemory() or memset() for your C++ structures that contain objects as structure members; that may corrupt their internal state and be the reason for a crash.
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <Windows.h>
#include <WinSock2.h>
#include <WS2tcpip.h>
#include <IPHlpApi.h>
#include <stdio.h>
#pragma comment(lib, "Ws2_32.lib")
#define DEFAULT_PORT "27015"//define the port on server by default which the client will connect to
#define DEFAULT_BUFLEN 512
int main(int argc, char *argv[]){
WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0){
printf("WSAStartup failed: %d\n", iResult);
return 1;
}
struct addrinfo *result = NULL,
*ptr = NULL,
hints;//Declare an addrinfo object that contains a sockaddr structure and initialize these values. For details of this struct, just check msdn
ZeroMemory(&hints, sizeof(hints));//just a macro definition of memset.
//Do not use ZeroMemory() or memset() for your C++ structures that contain objects as structure members;
//that may corrupt their internal state and be the reason for a crash.
hints.ai_family = AF_UNSPEC;//Unspecify the Internet address family so that either IPv4 or IPv6 can be returned.
hints.ai_socktype = SOCK_STREAM;//specify the socket type to be stream
hints.ai_protocol = IPPROTO_TCP;//use TCP protocol
//requesting the IP address for the server name passed on the command line stored in "result"
iResult = getaddrinfo(argv[1], DEFAULT_PORT, &hints, &result);
if (iResult != 0){ //check for errors
printf("getaddrinfo failed: %d\n", iResult);
WSACleanup();//WSACleanup is used to terminate the use of the WS2_32 DLL.
return 1;
}
SOCKET ConnectSocket = INVALID_SOCKET;//Create a SOCKET object
// Attempt to connect to the first address returned by
// the call to getaddrinfo
ptr = result;
//creates a socket that is bound to a specific transport service provider
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
//If the socket call fails, it returns INVALID_SOCKET.
if (ConnectSocket == INVALID_SOCKET){
//WSAGetLastError returns an error number associated with the last error that occurred.
printf("Error at socket(): %ld\n", WSAGetLastError());
freeaddrinfo(result);
WSACleanup();
return 1;
}
//Connect to server provided with the created socket and the sockdaddr structure
iResult = connect(ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
if (iResult == SOCKET_ERROR){
closesocket(ConnectSocket);
ConnectSocket = INVALID_SOCKET;
}
// Should really try the next address
//(Why? Be sure that "result" is a pointer to a linked list of one or more addrinfo structures)
//returned by getaddrinfo
// if the connect call failed
// But for this simple example we just free the resources
// returned by getaddrinfo and print an error message
freeaddrinfo(result);
if (ConnectSocket == INVALID_SOCKET){
printf("Unable to connect to server!\n");
WSACleanup();
return 1;
}
int recvbuflen = DEFAULT_BUFLEN;
char *sendbuf = "this is a test";
char recvbuf[DEFAULT_BUFLEN];
//The send and recv functions both return an integer value of the number of bytes sent or received, respectively,
//or an error.Each function also takes the same parameters : the active socket,
//a char buffer, the number of bytes to send or receive, and any flags to use.
iResult = send(ConnectSocket, sendbuf, (int)strlen(sendbuf), 0);
if (iResult == SOCKET_ERROR){
printf("send failed: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
printf("Bytes Sent: %ld\n", iResult);
// shutdown the connection for sending since no more data will be sent
// the client can still use the ConnectSocket for receiving data
iResult = shutdown(ConnectSocket, SD_SEND);
if (iResult == SOCKET_ERROR){
printf("shutdown failed: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
// Receive data until the server closes the connection
do{
iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
if (iResult > 0)
printf("Bytes received: %d\n", iResult);
else if (iResult == 0)
printf("Connection closed\n");
else
printf("recv failed: %d\n", WSAGetLastError());
} while (iResult > 0);
//cleanup
closesocket(ConnectSocket);
WSACleanup();
return 0;
}