这里是一个socket编程Demo,不考虑出错情况,代码简单,便于了解socket流程。
Demo分为服务器程序和客户端程序,运行需要先启动服务器程序,再启动客户端程序。
服务器会等待连接,客户端连接后,服务发送"connected."给客户端。
然后客户端会与服务器进行10次交互,一个交互为:客户端发一个消息,服务器收到,原样返回给客户端,客户端收到,再发下一个消息。
10次交互完成,关闭链接,两边程序都结束。
服务器程序:
#include <iostream>
#include <WinSock2.h>
#include <WS2tcpip.h>
#pragma comment (lib, "ws2_32.lib")
#define SOCKET_ADDR "127.0.0.1"
#define SOCKET_PORT 1234
int main()
{
WSADATA wsaData;
WSAStartup( MAKEWORD(2, 2), &wsaData);
SOCKET servSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
struct sockaddr_in sockAddr;
memset(&sockAddr, 0, sizeof(sockAddr));
sockAddr.sin_family = PF_INET;
inet_pton(AF_INET, SOCKET_ADDR, &sockAddr.sin_addr.s_addr);
sockAddr.sin_port = htons(SOCKET_PORT);
bind(servSock, (SOCKADDR*)&sockAddr, sizeof(SOCKADDR));
listen(servSock, 1);
SOCKADDR clntAddr;
int nSize = sizeof(SOCKADDR);
SOCKET clntSock = accept(servSock, (SOCKADDR*)&clntAddr, &nSize);
const char *str = "connected.";
send(clntSock, str, strlen(str)+sizeof(char), NULL);
int i = 10;
char szBuffer[MAXBYTE] = { 0 };
while (i != 0)
{
memset(szBuffer, 0, MAXBYTE);
recv(clntSock, szBuffer, MAXBYTE, NULL);
std::cout << szBuffer << std::endl;
send(clntSock, szBuffer, strlen(szBuffer)+ sizeof(char), NULL);
--i;
}
closesocket(clntSock);
closesocket(servSock);
WSACleanup();
return 0;
}
客户端程序:
#include <iostream>
#include <WinSock2.h>
#include <WS2tcpip.h>
#pragma comment(lib, "ws2_32.lib")
#define SOCKET_ADDR "127.0.0.1"
#define SOCKET_PORT 1234
int main()
{
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
SOCKET sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
struct sockaddr_in sockAddr;
sockAddr.sin_family = PF_INET;
inet_pton(AF_INET, SOCKET_ADDR, &sockAddr.sin_addr.s_addr);
sockAddr.sin_port = htons(SOCKET_PORT );
connect(sock, (SOCKADDR*)&sockAddr, sizeof(SOCKADDR));
char szBuffer[MAXBYTE] = {0};
recv(sock, szBuffer, MAXBYTE, NULL);
std::cout << szBuffer << std::endl;
int i = 10;
while (i != 0)
{
snprintf(szBuffer, MAXBYTE, "Index:%d", i);
send(sock, szBuffer, strlen(szBuffer) + sizeof(char), NULL);
std::cout << "send:" << szBuffer << std::endl;
memset(szBuffer, 0, MAXBYTE);
recv(sock, szBuffer, MAXBYTE, NULL);
std::cout << "recv:" << szBuffer <<std::endl;
--i;
}
closesocket(sock);
WSACleanup();
return 0;
}
客户端运行后输出:
connected.
send:Index:10
recy:Index:10
send:Index:9
recy:Index:9
send:Index:8
recy:Index:8
send:Index:7
recy:Index:7
send:Index:6
recy:Index:6
send:Index:5
recy:Index:5
send:Index:4
recy:Index:4
send:Index:3
recy:Index:3
send:Index:2
recy:Index:2
send:Index:1
recy:Index:1
两个程序在VS2019上编译运行通过。
主要交互在while里, 客户端这边是(发,收),服务器这边是(收, 发)。
Linux的socket与Windows类似,区别如下:
1.socket类型不同,
Windows: SOCKET(unsigned __int64)
Linux: int
2.收发函数不同:
Windows: recv/send
Linux: read/write
3.关闭socket不同:
Windows: closesocket(socket)
Linux: close(socket)