In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-17 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
This article introduces some functional analysis of socket, the content is very detailed, interested friends can refer to, hope to be helpful to you.
In network programming, the most commonly used and basic is WINSOCK. Now let's talk about SOCKET programming under WINDOWS.
Most WINSOCK programming on the WIN32 platform goes through the following steps:
Define variable-> get WINDOCK version-> load WINSOCK library-> initialize-> create socket-> set socket options-> close socket-> uninstall WINSOCK library-> release resources
The following describes the process of establishing WINSOCK Cramp S:
Server client
_ _ _
1 initialize WSA 1 initialize WSA
_ _ _
2 build a SOCKET 2 set up a SOCKET
_ _ _
3 bind SOCKET 3 to connect to the server
_ _ _
4 listen on the specified port 4 send and receive data
_ _ _
5 accept a connection 5 disconnect
_ _-
6 send and receive data
_ _ _
7 disconnect
_ _ _
Note that when you program WINSOCK in VC, you need to introduce the following two library files: WINSOCK.H (this is the header file of WINSOCK API, and WINSOCK2 is supported above WIN2K, so
You can use WINSOCK2.H); Ws2_32.lib (WINSOCK API link library file).
The mode of use is as follows:
# include
# pragma comment (lib, "ws2_32.lib")
Let's demonstrate the workflow of the server and client through specific code:
First, set up a WSADATA structure, usually using wsaData
WSADATA wsaData
Then, call the WSAStartup function, which is the first call to connect the application to winsock.dll. Where the first parameter is the WINSOCK version number, and the second parameter is to point to
The pointer of WSADATA. This function returns an int value, which is checked to determine whether initialization is successful. The format of the call is as follows: WSAStartup (MAKEWORD (2d2), & wsaData), where
MAKEWORD (2) means to use the WINSOCK2 version .wsaData to store the information about WINSOCK sent back by the system.
If (iResuit=WSAStartup (MAKEWORD (2Magazine 2), & wsaData)! = 0)
{
Printf ("WSAStartup failed:%d", GetLastError ()); / / the returned value is not equal to 0, indicating initialization failed
ExitProcess (); / / exit the program
}
After the application finishes using the requested SOCKET library, it calls the WSACleanup function to contact the binding of the SOCKET library and release the resources.
Note that after WSAStartup initialization, a SOCKET structure must be established to hold the SOCKET handle.
Let's build a SOCKET.
First we set up a SOCKET handle of m_socket, then call the socket () function, and the return value of the function is stored in m_socket. We use AF_INFE,SOCK_STREAM,IPPROTO_TCP
Three parameters. The first represents the address family, AF_INFE represents the TCP/ IP family, and the second represents the service type. In WINSOCK2, SOCKET supports the following three types
SOCK_STREAM streaming socket
SOCK_DGRAM Datagram socket
SOCK_RAW raw socket
The third parameter represents the protocol:
IPPROTO_UDP UDP protocol for connectionless Datagram sockets
IPPROTO_TCP TCP protocol for streaming sockets
IPPROTO_ICMP ICMP protocol is used for raw sockets
M_socket=socket (AF_INFE,SOCK_STREAM,IPPROTO_TCP); / / create TCP protocol
The following code is used to check the return value for errors:
If (m_scoket==INVALID_SOCKET)
{
Prinrf ("Error at socket ():% DBO", GetLastError ())
WSACleanup (); / / release resources
Return
}
Note that if the socket () call fails, he will return INVALID_SOCKET.
In order for the server to accept a connection, it must bind a network address. The following code shows how to bind an initialized IP and port Socket. The client program uses this.
IP address and port to connect to the server.
Sockaddr_in service
Service.sin_family=AF_INET; / / INTERNET address family
Service.sin_addr.s_addr=inet_addr ("127.0.0.1"); / / the local IP address to be bound
Service.sin_port=htons (27015); / / 27015 the port to be bound
Next we call the BIND function, pass in SOCKET and SOCKADDR as arguments, and check for errors.
If (bind (m_socket, (SOCKADDR*) & SERVICE,sizeof (service)) = = SOCKET_ERROR)
{
Printf ("bind () failed./n")
Closesocket (m_socket)
Return
}
When the binding is complete, the server must establish a listening queue to accept requests from the client. Listen () makes the server listen. The function call returns 0 successfully, otherwise it returns
SOCKET_ERROR. The code is as follows:
If (listen (masked socketMagne1) = = SOCKET-ERROR)
{
Printf ("error listening on socket./n")
}
After the server calls LISTEN (), if the client calls the CONNECT () function at this time, the server must call ACCEPT (). In this way, the server and the client can officially complete the communication program.
Connect the action.
Once the server starts listening, we specify a handle to represent the connection accepted by the ACCEPT () function, which is used to send and receive data. Create a SOCKET handle
Socket AcceptSocket then uses an infinite loop to detect whether a connection is coming in. As soon as there is a connection request, the ACCEPT () function is called and returns the handle to the connection.
Printf ("waitong for a client to connect.../n")
While (1)
{
AcceptSocket=SOCKET_ERROR
While (AcceptSocket==SOCKET_ERROR)
{
AcceptSocket=accept (masked socket _ null _ null)
}
}
Let's look at the client-side code:
Sockaddr_in clientService
ClientService.sin_family=AF_INET; / / INTERNET address family
ClientService.sin_addr.s_addr=inet_addr ("127.0.0.1"); / / the local IP address to be bound
ClientService.sin_port=htons (27015); / / 27015 the port to be bound
The CONNECT () function is called as follows:
If (connect (m_socket, (SOCKADDR*) & clientService, sizeof (clientService)) = = SOCKET_ERROR)
{
Printf ("Failed to connect./n")
WSACleanup ()
Return
} / / Clean out if the call fails
/ / the call continues to read and write data successfully
_
At this point, the basic flow of the server and client is introduced, and let's introduce the data exchange.
Send ():
Int send
{
SOCKET s, / / specify the sending end socket
Const char FAR?*buf, / / indicates a buffer for data to be sent by the application
Int len, / / actual number of bytes of data to be sent
Int flags / / is generally set to 0
}
The SEND function is used to send data to the other end of the TCP connection.
Recv ():
Int recv
{
SOCKET s, / / specify the sending end socket
Char FAR?*buf, / / indicates a buffer to store the data received by RECC
Int len, / / indicates the length of the BUF
Int flags / / is generally set to 0
}
The RECV function is used to accept data from the other end of the TCP connection.
The following complete program code is provided as follows. You can compile and run the client code directly: # include # include # pragma comment (lib, "ws2_32.lib") void main () {/ / initialize Winsock. WSADATA wsaData; int iResult = WSAStartup (MAKEWORD (2jing2), & wsaData); if (iResult! = NO_ERROR) printf ("Error at WSAStartup () / n"); / / establish socket socket. SOCKET client; client = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); if (client = = INVALID_SOCKET) {printf ("Error at socket ():% ld/n", WSAGetLastError ()); WSACleanup (); return;} / / Connect to the server. Sockaddr_in clientService; clientService.sin_family = AF_INET; clientService.sin_addr.s_addr = inet_addr ("127.0.0.1"); clientService.sin_port = htons (27015); if (connect (client, (SOCKADDR*) & clientService, sizeof (clientService)) = = SOCKET_ERROR) {printf ("Failed to connect./n"); WSACleanup (); return;} / / send and receive data. Int bytesSent; int bytesRecv = SOCKET_ERROR; char sendbuf [32] = "Client: Sending data."; char recvbuf [32] = ""; bytesSent = send (client, sendbuf, strlen (sendbuf), 0); printf ("Bytes Sent:% ld/n", bytesSent); while (bytesRecv = = SOCKET_ERROR) {bytesRecv = recv (client, recvbuf, 32,0); if (bytesRecv = 0 | bytesRecv = = WSAECONNRESET) {printf ("Connection Closed./n"); break;} if (bytesRecv)
< 0) return; printf( "Bytes Recv: %ld/n", bytesRecv ); } return; } 下面是服务器端代码: #include #include #pragma comment(lib, "ws2_32.lib") void main() { // 初始化 WSADATA wsaData; int iResult = WSAStartup( MAKEWORD(2,2), &wsaData ); if ( iResult != NO_ERROR ) printf("Error at WSAStartup()/n"); // 建立socket SOCKET server; server = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP ); if ( server == INVALID_SOCKET ) { printf( "Error at socket(): %ld/n", WSAGetLastError() ); WSACleanup(); return; } // 绑定socket sockaddr_in service; service.sin_family = AF_INET; service.sin_addr.s_addr = inet_addr( "127.0.0.1" ); service.sin_port = htons( 27015 ); if ( bind( server, (SOCKADDR*) &service, sizeof(service) ) == SOCKET_ERROR ) { printf( "bind() failed./n" ); closesocket(server); return; } // 监听 socket if ( listen( server, 1 ) == SOCKET_ERROR ) printf( "Error listening on socket./n"); // 接受连接 SOCKET AcceptSocket; printf( "Waiting for a client to connect.../n" ); while (1) { AcceptSocket = SOCKET_ERROR; while ( AcceptSocket == SOCKET_ERROR ) { AcceptSocket = accept( server, NULL, NULL ); } printf( "Client Connected./n"); server = AcceptSocket; break; } // 发送接受数据 int bytesSent; int bytesRecv = SOCKET_ERROR; char sendbuf[32] = "Server: Sending Data."; char recvbuf[32] = ""; bytesRecv = recv( server, recvbuf, 32, 0 ); printf( "Bytes Recv: %ld/n", bytesRecv ); bytesSent = send( server, sendbuf, strlen(sendbuf), 0 ); printf( "Bytes Sent: %ld/n", bytesSent ); return; } 本程序仅仅描述了同步的情况! PS:本文转自百度贴吧新红盟吧 转自:http://blog.csdn.net/LaoWu_/archive/2010/04/08/5461077.aspx关于gethostname函数失败的问题 调用gethostname之前, 要先调用WSAStartup才可以, 否则gethostname会失败! 下面是正确的代码 view plaincopy to clipboardprint? #include #include #include #include #include #pragma comment(lib, "Ws2_32") int main() { WSADATA wsData; ::WSAStartup(MAKEWORD(2,2), &wsData); char szIP[32] = {0}; char szHostName[32] = {0}; int iResult = ::gethostname(szHostName, sizeof(szHostName)); if (iResult != 0) { printf("error/n"); return -1; } printf("%s/n", szHostName); hostent *pHost = ::gethostbyname(szHostName); ::WSACleanup(); return 0; } 转自:http://blog.csdn.net/leesphone/archive/2008/03/02/2138775.aspx gethostbyname用法使用这个东西,首先要包含2个头文件: #include #include struct hostent *gethostbyname(const char *name); 这个函数的传入值是域名或者主机名,例如"www.google.com","wpc"等等。 传出值,是一个hostent的结构(如下)。如果函数调用失败,将返回NULL。 struct hostent { char *h_name; char **h_aliases; int h_addrtype; int h_length; char **h_addr_list; }; 解释一下这个结构, 其中: char *h_name 表示的是主机的规范名。例如www.google.com的规范名其实是www.l.google.com。 char **h_aliases 表示的是主机的别名。www.google.com就是google他自己的别名。有的时候,有的主机可能有好几个别名,这些,其实都是为了易于用户记忆而为自己的网站多取的名字。 int h_addrtype 表示的是主机ip地址的类型,到底是ipv4(AF_INET),还是ipv6(AF_INET6) int h_length 表示的是主机ip地址的长度 int **h_addr_lisst 表示的是主机的ip地址,注意,这个是以网络字节序存储的。千万不要直接用printf带%s参数来打这个东西,会有问题的哇。所以到真正需要打印出这个IP的话,需要调用inet_ntop()。 const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt) : 这个函数,是将类型为af的网络地址结构src,转换成主机序的字符串形式,存放在长度为cnt的字符串中。 这个函数,其实就是返回指向dst的一个指针。如果函数调用错误,返回值是NULL。 下面是例程,有详细的注释。 #include #include int main(int argc, char **argv) { char *ptr,**pptr; struct hostent *hptr; char str[32]; /* 取得命令后第一个参数,即要解析的域名或主机名 */ ptr = argv[1]; /* 调用gethostbyname()。调用结果都存在hptr中 */ if( (hptr = gethostbyname(ptr) ) == NULL ) { printf("gethostbyname error for host:%s/n", ptr); return 0; /* 如果调用gethostbyname发生错误,返回1 */ } /* 将主机的规范名打出来 */ printf("official hostname:%s/n",hptr->H_name)
/ * the host may have multiple aliases. Type all aliases separately * /
For (pptr = hptr- > hackers; * pptr! = NULL; pptr++)
Printf ("alias:%s/n", * pptr)
/ * type the address according to the address type * /
Switch (hptr- > h_addrtype)
{
Case AF_INET:
Case AF_INET6:
Pptr=hptr- > h_addr_list
/ * type out all the addresses you just got. The inet_ntop () function * / is called.
For (; * pptryside null +)
Printf ("address:%s/n", inet_ntop (hptr- > h_addrtype, * pptr, str, sizeof (str))
Break
Default:
Printf ("unknown address type/n")
Break
}
Return 0
}
Transferred from: http://blog.csdn.net/chollima/archive/2010/06/04/5648065.aspx
Gethostname and gethostbyname,inet_ntoaview plaincopy to clipboardprint?
/ / socketTest.cpp: Defines the entry point for the console application.
/ /
# include "stdafx.h"
# include
# include
Using namespace std
Int _ tmain (int argc, _ TCHAR* argv [])
{
WSADATA wsData = {0}
Int nRet =:: WSAStartup (MAKEWORD (2,2), & wsData)
Char szBuf [Max _ PATH] = {0}
:: gethostname (szBuf, MAX_PATH); / / get the computer name
Struct hostent* pStHostent = NULL
Strcpy (szBuf, "www.google.com")
PStHostent =:: gethostbyname (szBuf); / / pass in the domain name or hostname to get the host structure
/ *
PStHostent- > hsignname; / / Specification name
PStHostent- > html addrtypespare / address type IPV4 or IPV6
The IP address of pStHostent- > hobbies, listeners, racket, etc
PStHostent- > html address length; / / ip address length
PStHostent- > html aliasesumbent / host alias
, /
Cout h_name h_addrtype)
{
Case AF_INET:
Case AF_INET6:
Pptr = pStHostent- > h_addr_list
For (; * pptr! = NULL; pptr++)
{
/ / addr.S_un.S_addr = * (upright long *) * pptr
Addr.s_addr = * (upright long *) * pptr
/ / print out a list of IP addresses
Cout
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.