network programming
The behavior of exchanging data between two or more computers that have been networked is network programming. The
operating system we use every day has provided us with sockets, and we
can master network programming without being familiar with the principles of network data transmission.
What is the difference between socket in windows and socket in Linux?
- same
Linux
It is usually文件描述符
used to indicate or distinguish files that have been opened;windows
文件句柄
Represented by the way, and the above isLinux
a文件描述符
similar concept;- different
Linux
Everything is a file, so a network connection is also a file.Windows
It will besocket
distinguished from the file, so the data transfer function is designed in a targeted mannerWindows
.socket
socket type
- SOCK_STREAM
面向连接的套接字(Stream Sockets)
, isSOCK_STREAM
the right explanation. The protocol
is usedTCP
and has its own error correction mechanism. The protocol
used by the browserhttp
is based on面向连接的套接字
- SOCK_DGRAM
无连接的套接字(Datagram Sockets)
, also called数据报格式套接字
.
Its transmission efficiency is relativelySOCK_STREAM
high, but the work of verifying data is less.
Video chat and voice video are mostly used无连接套接字
to transmit data.
- SOCK_RAW
原始套接字(raw-protocol interface)
.The
complete header of the data packet is savedIP
, and the data can be analyzed through it.
Network security products usually use this type, such asMAC
address scanners, network sniffers and other products.
TCP socket
- Server
#include <iostream>
#include <WinSock2.h>
#pragma comment(lib,"ws2_32.lib")
using namespace std;
int main()
{
//初始化套接字库
WORD wVersion;
WSADATA wsaData;
int err;
wVersion = MAKEWORD(1, 1);
err = WSAStartup(wVersion, &wsaData);
//检查
if (err != 0)
{
return err;
}
if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)
{
//清理套接字库
WSACleanup();
return -1;
}
//创建套接字
SOCKET sockSrv = socket(AF_INET, SOCK_STREAM, 0);
//准备绑定的信息
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(6000);
//绑定到本机
bind(sockSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));
//监听
listen(sockSrv, 10);
cout << "server start at prot: 6000" << endl;
SOCKADDR addrCli;
int len = sizeof(SOCKADDR);
char recvBuf[100];
char sendBuf[100];
while (true)
{
//接受连接请求
SOCKET sockConn = accept(sockSrv, (SOCKADDR*)&addrCli, &len);
sprintf_s(sendBuf,100, "hello");
send(sockConn, sendBuf, strlen(sendBuf) + 1, 0);
//接受或发送数据
recv(sockConn, recvBuf, 100, 0);
std::cout << recvBuf << std::endl;
//关闭套接字
closesocket(sockConn);
}
//关闭套接字
closesocket(sockSrv);
//清理套接字库
WSACleanup();
system("pause");
return 0;
}
- client
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <iostream>
#include <WinSock2.h>
#pragma comment(lib,"ws2_32.lib")
using namespace std;
int main()
{
//初始化套接字库
WORD wVersion;
WSADATA wsaData;
int err;
wVersion = MAKEWORD(1, 1);
err = WSAStartup(wVersion, &wsaData);
//检查
if (err != 0)
{
return err;
}
if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)
{
//清理套接字库
WSACleanup();
return -1;
}
//创建tcp套接字
SOCKET sockCli = socket(AF_INET, SOCK_STREAM, 0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr = inet_addr("192.168.0.131");
//addrSrv.sin_addr.S_un.S_addr = htons(6000);//大失误
addrSrv.sin_port = htons(6000);
addrSrv.sin_family = AF_INET;
//连接服务器
connect(sockCli, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));
char sendBuf[] = "world";
char recvBuf[100];
//发送数据到服务器
send(sockCli, sendBuf, strlen(sendBuf) + 1, 0);
//接收服务器发送的数据
recv(sockCli, recvBuf, sizeof(recvBuf), 0);
cout << recvBuf << endl;
closesocket(sockCli);
WSACleanup();
system("pause");
return 0;
}
UDP socket
- Server
#include <iostream>
#include <WinSock2.h>
#pragma comment(lib,"ws2_32.lib")
using namespace std;
int main()
{
//初始化套接字库
WORD wVersion;
WSADATA wsaData;
wVersion = MAKEWORD(1, 1);
int err = WSAStartup(wVersion, &wsaData);
//检查
if (err != 0)
{
cout << WSAGetLastError() << endl;
return err;
}
if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)
{
cout << WSAGetLastError() << endl;
WSACleanup();
return -1;
}
//创建套接字
SOCKET sockSrv = socket(AF_INET, SOCK_DGRAM, 0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
addrSrv.sin_port = htons(6002);//主机字节序转换
addrSrv.sin_family = AF_INET;
//绑定到本机6002端口
bind(sockSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));
//接受请求,处理请求
SOCKADDR_IN addrCli;
int len = sizeof(SOCKADDR);
char sendBuf[] = "UDP Server ...";
char recvBuf[100];
cout << "Start UDP Server with port 6002 " << endl;;
while (true)
{
//接收数据
recvfrom(sockSrv, recvBuf, 100, 0, (SOCKADDR*)&addrCli, &len);
cout << "Recv: " << recvBuf << endl;
//发送数据
sendto(sockSrv, sendBuf, strlen(sendBuf) + 1, 0, (SOCKADDR*)&addrCli, len);
cout << "Send: " << sendBuf << endl;
}
//关闭套接字并清除套接字库
closesocket(sockSrv);
WSACleanup();
system("pause");
return 0;
}
- client
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <iostream>
#include <WinSock2.h>
#pragma comment(lib,"ws2_32.lib")
using namespace std;
int main()
{
//初始化套接字库
WORD wVersion;
WSADATA wsaData;
wVersion = MAKEWORD(1, 1);
int err = WSAStartup(wVersion, &wsaData);
//检查
if (err != 0)
{
return err;
}
if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)
{
WSACleanup();
return -1;
}
//创建UDP套接字
SOCKET sockCli = socket(AF_INET, SOCK_DGRAM, 0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
addrSrv.sin_port = htons(6002);
addrSrv.sin_family = AF_INET;
SOCKADDR_IN addrCli;
int len = sizeof(SOCKADDR);
char sendBuf[] = "send from UDP client ...";
char recvBuf[100];
//发送数据到服务端并打印
cout << "send to server: " << sendBuf << endl;
sendto(sockCli, sendBuf, strlen(sendBuf) + 1, 0, (SOCKADDR*)&addrSrv, len);
//接收服务端数据并打印
recvfrom(sockCli, recvBuf, 100, 0, (SOCKADDR*)&addrCli, &len);
cout << "receve from: " << recvBuf << endl;
//关闭套接字并清除套接字库
closesocket(sockCli);
WSACleanup();
system("pause");
return 0;
}
Analysis of common functions
- WSAStartup() function
It is
Windows
a function specific to the operating system. When using network programming in the system, it is necessary to load
the dynamic link library. Before using this function, it is necessary to call the function to initialize the dynamic library.Windows
ws2_32.dll
dll
WSAStartup()
Function prototype:
int WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData);
- socket() function
The program uses
socket
a function to create a socket, whether it isLinux
orWindows
is the same, the difference is that the return value is different. The return value of the function
Linux
in the middle is , and the return value in the middle is . The environment I am practicing here is , so the code examples here are subject to .socket
int
Windows
SOCKET
windows
Windows
Function prototype:
SOCKET socket(int af, int type, int protocol);
- bind() function
After creating the socket, you need to determine various attributes of the socket, such as
IP
address, port and other information.
These information aresockaddr
stored in a structure variable.
Function prototype:
int bind(SOCKET sock, const struct sockaddr *addr, int addrlen);
- connect() function
It is used by the client to establish a connection after creating a socket.
Its parameters arebind
the same as
Function prototype:
int connect(SOCKET sock, const struct sockaddr *serv_addr, int addrlen);
- listen() function
After the server binds the socket, it also uses
listen
the function to make the socket enter the passive listening state.
The second parameter is the maximum length of the request queue.
Function prototype:
int listen(SOCKET sock, int backlog);
- accept() function
After the socket
listen
enters the passive listening state through the function,accept
it receives the client request through the function.
Its parameters are the samelisten
asconnect
the function.
Function prototype:
SOCKET accept(SOCKET sock, struct sockaddr *addr, int *addrlen);
- send() function
The purpose of the above series of connections is naturally to realize the sending and receiving of data between the server and the client. The
send
function is to send data from the server, and the fourth parameter can refer to the flags parameter in the send recv function
Function prototype:
int send(SOCKET sock, const char *buf, int len, int flags);
- recv() function
recv
The function of the function is to receive data from the server or client.
Itsend
is the same as the parameter of the function.
Function prototype:
int recv(SOCKET sock, char *buf, int len, int flags);
Summarize
This blog content simply covers socket
the functions needed for programming,
and gives simple sample codes. socket
It is still helpful for getting started with programming.\
Windows
The socket functions extended by the operating system generally WSA
start with, which means Windows socket API
. Commonly used ones such as:
WSASend
, WSARecv
and the ones mentioned above WSACleanup
.