// TcpClient.cpp : 定义控制台应用程序的入口点。 //
#include “stdafx.h”
#include <Winsock2.H> #include #include #include <stdio.h>
#pragma comment(lib,“WS2_32.lib”) #define BUF_SIZE 4096 // 缓冲区大小
int _tmain(int argc, _TCHAR* argv[]) { WSADATA wsd; // 用于初始化Windows Socket SOCKET sHost; // 与服务器进行通信的套接字 SOCKADDR_IN servAddr; // 服务器地址 char buf[BUF_SIZE]; // 用于接受数据缓冲区 int retVal; // 调用各种Socket函数的返回值 // 初始化Windows Socket if(WSAStartup(MAKEWORD(2,2),&wsd) != 0) { printf(“WSAStartup failed !\n”); return 1; } // 创建套接字 sHost = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); if(INVALID_SOCKET == sHost) { printf(“socket failed !\n”); WSACleanup(); return -1; } // 设置服务器地址 servAddr.sin_family = AF_INET; servAddr.sin_addr.S_un.S_addr = inet_addr(“127.0.0.1”); // 用户需要根据实际情况修改 servAddr.sin_port = htons(9990); // 在实际应用中,建议将服务器的IP地址和端口号保存在配置文件中 int sServerAddlen = sizeof(servAddr); // 计算地址的长度 // 连接服务器 retVal = connect(sHost,(LPSOCKADDR)&servAddr,sizeof(servAddr)); // 循环等待 while (INVALID_SOCKET == retVal) { if(INVALID_SOCKET == retVal) { int err = WSAGetLastError(); if(err == WSAEWOULDBLOCK) // 无法立即完成非阻塞套接字上的操作 { //Sleep(500); continue; } else { printf(“accept failed !\n”); closesocket(sHost); WSACleanup(); return -1; } } } // 循环向服务器发送字符串,并显示反馈信息。 // 发送quit将使服务器程序退出,同时客户端程序自身也将退出 while(true) { // 向服务器发送数据 printf("Please input a string to send: "); // 接收输入的数据 //以下是C++方式获得字符串
std::string str;
std::getline(std::cin, str);
// 将用户输入的数据复制到buf中
ZeroMemory(buf,BUF_SIZE);
strcpy(buf,str.c_str());
/*//以下是C语言方式获得字符串
char buf2[50];
ZeroMemory(buf2, 50);
//scanf("%s",buf2);
gets_s(buf2);
//使用C语言方式获得字符串时需要特别注意,在send和recv函数中的缓冲区长度字段应设置为与发送字符串相同的大小,否则出现乱码*/
// 向服务器发送数据
//retVal = send(sHost,buf, 50,0); //C语言方式获得字符串,指定缓冲区长度大小
retVal = send(sHost, buf, strlen(buf), 0); //C++方式获取字符串按系统设定缓冲区大小即可,可以与发送字符串长度不相同
if(SOCKET_ERROR == retVal)
{
printf("send failed !\n");
closesocket(sHost);
WSACleanup();
return -1;
}
// 接收服务器回传的数据
//retVal = recv(sHost,buf,50,0);
retVal = recv(sHost, buf, sizeof(buf)+1, 0);
printf("Recv From Server: %s\n",buf);
// 如果收到quit,则退出
if(strcmp(buf, "quit") == 0)
{
printf("quit!\n");
break;
}
}
// 释放资源
closesocket(sHost);
WSACleanup();
// 暂停,按任意键继续
system("pause");
return 0;
}
//TCPServer.cpp 程序服务端 #include “stdafx.h” #include <WinSock2.h> #include #include <tchar.h> #pragma comment(lib,“WS2_32.lib”)
#define BUF_SIZE 4096
int _tmain(int argc, _TCHAR* argv[]) { WSADATA wsd; //WSADATA变量,用于初始化Windows Sockets SOCKET sServer; //服务器Socket,用于监听客户端请求 SOCKET sClient; //客户端Socket,用于实现与客户端的通信 int retVal; //调用各种Socket函数的返回值 char buf[BUF_SIZE]; //用于接收客户端数据的缓冲区
//初始化Socket动态库
if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)
{
printf("WSAStartup failed !\n");
return -1;
}
//创建用于监听的Socket
sServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (INVALID_SOCKET == sServer)
{
printf("socket failed !\n");
WSACleanup();//销毁资源
return -1;
}
//设置服务器Socket地址
SOCKADDR_IN addrServ; //服务器的地址信息
addrServ.sin_family = AF_INET; //ipv4协议
addrServ.sin_port = htons(9990); //监听端口为9990
addrServ.sin_addr.S_un.S_addr = htonl(INADDR_ANY); //绑定的是主机任一可用的ip地址
//addrServ.sin_addr.S_un.S_addr = inet_addr("ip地址");
//绑定Sockets Server到本地地址
retVal = bind(sServer, (const struct sockaddr*)&addrServ, sizeof(SOCKADDR_IN));
if (SOCKET_ERROR == retVal)//retVal !=0
{
printf("bind failed !\n");
closesocket(sServer);
WSACleanup();
return -1;
}
//在Sockets Server上监听
retVal = listen(sServer, 1);
if (SOCKET_ERROR == retVal)
{
printf("listen failed !\n");
closesocket(sServer);
WSACleanup();
return -1;
}
//接收来自客户端的请求
printf("TCP Server start...\n");
sockaddr_in addrClient; //客户端地址
int addrClientlen = sizeof(addrClient);
sClient = accept(sServer, (sockaddr FAR*) & addrClient, &addrClientlen);
if (INVALID_SOCKET == sClient)
{
printf("accept failed !\n");
closesocket(sServer);
WSACleanup();
return -1;
}
//循环接收客户端的数据,直接客户端发送给quit命令后退出
while (true)
{
ZeroMemory(buf, BUF_SIZE); //清空接收数据的缓冲区
retVal = recv(sClient, buf, BUFSIZ, 0);
if (SOCKET_ERROR == retVal)
{
printf("recv failed !\n");
closesocket(sServer);
closesocket(sClient);
WSACleanup();
return -1;
}
//获取当前系统时间
SYSTEMTIME st;
GetLocalTime(&st);
char sDateTime[30];
sprintf(sDateTime, "%4d-%2d-%2d %2d:%2d:%2d", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
printf("%s,Recv From Client [%s:%d] :%s\n", sDateTime,inet_ntoa(addrClient.sin_addr),addrClient.sin_port,buf);
//如果客户端发送quit字符串,则服务器退出
if (strcmp(buf, "quit") == 0)
{
retVal = send(sClient, "quit", strlen("quit"), 0);
break;
}
//否则向客户端发送回显字符串
else
{
char msg[BUF_SIZE];
sprintf(msg, "Message received - %s", buf); //向客户端发送回显字符串
retVal = send(sClient, msg, strlen(msg), 0);
if (SOCKET_ERROR == retVal)
{
printf("send failed !\n");
closesocket(sServer);
closesocket(sClient);
WSACleanup();
return -1;
}
}
}
//释放Socket
closesocket(sServer);
closesocket(sClient);
WSACleanup();
//暂停,按任意键退出
system("pause");
return 0;
}
|