TCP协议(三)之Windows实现
tcp 编程一般的步骤:
server(服务端)
1.new 个 socket
2.bind (IP,port)
3.listen,等待客户端的连接
4.accept 接受客户端的连接
5.接收(recv) 发送数据(send)
6.关闭连接
client(客户端)
1.new 个 socket
2.bind(ip,port)
3.connect (server.ip,server,port)
4.recv() /send()
5.关闭连接
2.程序
服务器程序
#include <stdlib.h>
#include <stdio.h>
#include <WinSock2.h>
#pragma comment(lib,"Ws2_32.lib ")
int main()
{
WSADATA wsaData;
struct sockaddr_in servAddr;
struct sockaddr_in cliAddr;
if (WSAStartup(MAKEWORD(2, 2), &wsaData))
{
printf("Error:RequestWindowsSocketLibrary failed!\n");
return 0;
}
/* 设置IP地址 */
memset(&servAddr, 0, sizeof(servAddr));
servAddr.sin_addr.s_addr = htonl(INADDR_ANY); //绑定本机IP
//servAddr.sin_addr.s_addr = inet_addr("192.168.1.53");
/* 设置端口 */
servAddr.sin_family = AF_INET;
servAddr.sin_port = htons(3000); //端口为3000
/* 创建套接服务字 */
SOCKET serverSocket;
serverSocket = socket(AF_INET, SOCK_STREAM, 0);
if (serverSocket == INVALID_SOCKET)
{
printf("Error:CreatServerSocket failed!\n");
return 0;
}
/* 绑定服务器套接字 */
if (bind(serverSocket, (sockaddr*)&servAddr, sizeof(sockaddr)) == SOCKET_ERROR)
{
printf("ERROR:Bind failed!\n");
return 0;
}
/* 监听端口 */
if (listen(serverSocket, 20) == SOCKET_ERROR)
{
closesocket(serverSocket);
WSACleanup();
printf("ERROR:Listen failed!\n");
return 0;
}
printf("linstening:%dport...\n", ntohs(servAddr.sin_port));
/* 阻塞方式等待accept */
int len = sizeof(cliAddr);
SOCKET clientSocket;
clientSocket = accept(serverSocket, (sockaddr*)&cliAddr, &len);
printf("Connected:%s \r\n", inet_ntoa(cliAddr.sin_addr));
/* 接受消息 */
char recvBuf[100] = { 0 };
recv(clientSocket, recvBuf, sizeof(recvBuf), 0);
/* 发送消息 */
send(clientSocket, recvBuf, 100, NULL);
closesocket(clientSocket);
WSACleanup();
system("pause");
return 1;
}
客户端代码
#include "stdlib.h"
#include <stdio.h>
#include <WinSock2.h>
#pragma comment(lib, "ws2_32.lib") //加载 ws2_32.dll
int main()
{
//初始化DLL
//主版本号(低字节)为2,副版本号为2,返回 0x0202
WORD sockVersion = MAKEWORD(2, 2);
WSADATA wsaData;
//WSAStartup() 函数执行成功后,会将与 ws2_32.dll 有关的信息写入 WSAData 结构体变量
//(只需关注前两个成员即可)
if (WSAStartup(sockVersion, &wsaData) != 0)
return 0;
//创建套接字,socket() 函数用来创建套接字,确定套接字的各种属性
//IPv4 地址、面向连接的数据传输方式、TCP 传输协议
SOCKET sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
//向服务器发起请求,将创建的套接字与IP地址 101.76.220.219、端口 3000 绑定:
sockaddr_in sockAddr;
memset(&sockAddr, 0, sizeof(sockAddr));
sockAddr.sin_family = PF_INET;
//32位IP地址,s_addr 是一个整数(unsigned long),而IP地址是一个字符串,
//所以需要 inet_addr() 函数进行转换
sockAddr.sin_addr.s_addr = inet_addr("101.76.218.229");
//16位的端口号,端口号需要用 htons() 函数转换,0~1023 的端口一般由系统分配给特定的服务程序,
//尽量在 1024~65536 之间分配端口号。
sockAddr.sin_port = htons(3000);
//强制类型转换,服务器端要用 bind() 函数将套接字与特定的IP地址和端口绑定起来,
//只有这样,流经该IP地址和端口的数据才能交给套接字处理
while (connect(sock, (SOCKADDR*)& sockAddr, sizeof(SOCKADDR)) == SOCKET_ERROR)
{
printf("连接失败\n");
Sleep(1000);
}
printf("成功连接到服务器!\n");
char sendBuf[100] = {"Hello World"};
send(sock, sendBuf, 100, NULL);
char recvBuf[100] = { 0 };
recv(sock, recvBuf, 100, 0);
closesocket(sock);
WSACleanup();
for (int i = 0; i < 12; i++)
{
printf("%c",recvBuf[i]);
}
system("pause");
return 1;
}
浙公网安备 33010602011771号