套接字,是支持TCP/IP的网络通信的基本操作单元,可以看做是不同主机之间的进程进行双向通信的端点,简单的说就是通信的两方的一种约定,用套接字中的相关函数来完成通信过程。按照往例,话不多说,直接上Demo:
Server端:
// SocketServer.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <winsock2.h>
#pragma comment(lib, "WS2_32") // 链接到WS2_32.lib
#include <WS2tcpip.h>
int main()
{
// 初始化WS2_32.dll
WSADATA WsaData = {0};
WORD SocketVersion = MAKEWORD(2, 2);
if (WSAStartup(SocketVersion, &WsaData) != 0)
{
printf("Can't Init Socket!\r\n");
return 0;
}
// 创建套接字
SOCKET ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);//IPv4协议,TCP协议,TCP封包
if (ListenSocket == INVALID_SOCKET)
{
printf("Failed socket()!\r\n");
return 0;
}
// 填充sockaddr_in结构
sockaddr_in ServerAddr;
ServerAddr.sin_family = AF_INET;
ServerAddr.sin_port = htons(4567);
ServerAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
// 绑定这个套节字到一个本地地址
if (bind(ListenSocket, (LPSOCKADDR)&ServerAddr, sizeof(ServerAddr)) == SOCKET_ERROR)
{
printf("Failed bind()! \r\n");
closesocket(ListenSocket);
WSACleanup();
return 0;
}
// 进入监听模式
if (listen(ListenSocket, 2) == SOCKET_ERROR)
{
printf("Failed listen()!\r\n");
closesocket(ListenSocket);
WSACleanup();
return 0;
}
// 循环接受客户的连接请求
sockaddr_in ClientAddr;
int AddrLength = sizeof(ClientAddr);
SOCKET AcceptSocket;
char SendBuffer[] = "TCP Server! \r\n";
while (TRUE)
{
// 接受一个新连接
AcceptSocket = accept(ListenSocket, (SOCKADDR*)&ClientAddr, &AddrLength);
if (AcceptSocket == INVALID_SOCKET)
{
closesocket(ListenSocket);
WSACleanup();
printf("Failed accept()!\r\n");
continue;
}
char Buffer[16] = { 0 };
printf("Accept a New Client:%s \r\n", inet_ntop(AF_INET, &ClientAddr.sin_addr,Buffer,16));
// 接收数据
char RecvBuffer[256];
int BufferLength = recv(AcceptSocket, RecvBuffer, 256, 0);
if (BufferLength > 0)
{
RecvBuffer[BufferLength] = '\0';
printf("Recived Buffer:%s", RecvBuffer);
}
// 向客户端发送数据
send(AcceptSocket, SendBuffer, strlen(SendBuffer), 0);
// 关闭同客户端的连接
closesocket(AcceptSocket);
}
// 关闭监听套节字
closesocket(ListenSocket);
WSACleanup();
return 0;
}
Client端:
// SocketClient.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <winsock2.h>
#pragma comment(lib, "WS2_32") // 链接到WS2_32.lib
#include <WS2tcpip.h>
int main()
{
// 初始化WS2_32.dll
WSADATA WsaData;
WORD SocketVersion = MAKEWORD(2, 2);
if (WSAStartup(SocketVersion, &WsaData) != 0)
{
printf("Can't Init Socket!\r\n");
return 0;
}
// 创建套接字
SOCKET ClientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (ClientSocket == INVALID_SOCKET)
{
printf(" Failed socket()!\r\n");
WSACleanup();
return 0;
}
// 也可以在这里调用bind函数绑定一个本地地址
// 否则系统将会自动安排
// 填写远程地址信息
sockaddr_in ServerAddr;
ServerAddr.sin_family = AF_INET;
ServerAddr.sin_port = htons(4567);
// 注意,这里要填写服务器程序(TCPServer程序)所在机器的IP地址
// 如果你的计算机没有联网,直接使用127.0.0.1即可
ServerAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
if (connect(ClientSocket, (sockaddr*)&ServerAddr, sizeof(ServerAddr)) == SOCKET_ERROR)
{
printf(" Failed connect()!\r\n");
closesocket(ClientSocket);
WSACleanup();
return 0;
}
char SendBuffer[] = "TCP Client Connect! \r\n";
// 向服务端发送数据
send(ClientSocket, SendBuffer, strlen(SendBuffer), 0);
// 接收数据
char RecvBuffer[256];
int BufferLength = recv(ClientSocket, RecvBuffer, 256, 0);
if (BufferLength > 0)
{
RecvBuffer[BufferLength] = '\0';
printf(" Recived Buffer:%s", RecvBuffer);
}
// 关闭套节字
closesocket(ClientSocket);
WSACleanup();
getchar();
getchar();
return 0;
}