代码来自书上,主要是了解过程。
服务器代码
// P97_TcpServer.cpp : 定义控制台应用程序的入口点。
//
/**
* wsa2库, creat socket, set addr, bind, listen, accept request,
*
**/
#include "stdafx.h"
//#include <WinSock2.h>
//#include <Windows.h>
//#pragma comment (lib, "WS2_32.lib")
#define BUF_SIZE 64
int _tmain(int argc, _TCHAR* argv[])
{
WSADATA wsaData;
SOCKET listenSock;
SOCKET acceptSock;
char Serverbuf[BUF_SIZE];
// 初始化Socket动态库
if ( WSAStartup(MAKEWORD(2,2), &wsaData) != 0){
printf("WSAStartup falid.\n");
WSACleanup();
exit(1);
}
// 创建Socket
if ((listenSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET){
printf("Creat listenSock failed\n");
WSACleanup();
exit(1);
}
// 设置服务器地址信息
SOCKADDR_IN addrServ;
addrServ.sin_family = AF_INET;
addrServ.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
addrServ.sin_port = htons(9990);
// 绑定套接字与端口
if (bind(listenSock, (sockaddr*) &addrServ, sizeof(addrServ)) == SOCKET_ERROR){
printf("bind faild\n");
closesocket(listenSock);
WSACleanup();
exit(1);
}
// 监听套接字
if (listen(listenSock, 5) == SOCKET_ERROR){
printf("listen faild\n");
closesocket(listenSock);
WSACleanup();
exit(1);
}
// 接受客户端连接
// 需要保存客户端地址信息
printf("Tcp Server start...\n\n");
SOCKADDR_IN addrClient;
int addrClientLen = sizeof(addrClient);
if ((acceptSock = accept(listenSock, (sockaddr*)&addrClient, &addrClientLen)) == INVALID_SOCKET){
printf("accept listenSock failed\n");
closesocket(listenSock);
closesocket(acceptSock);
WSACleanup();
exit(1);
}
// 循环接受客户端数据,直到收到quit命令
while (true){
ZeroMemory(Serverbuf, BUF_SIZE);// 清空缓冲区
if ( recv(acceptSock, Serverbuf, BUF_SIZE, 0) == SOCKET_ERROR){
printf("recv failed.\n");
closesocket(listenSock);
closesocket(acceptSock);
WSACleanup();
exit(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 :%s\n", sDateTime, Serverbuf);
// if content is "quit", then Server quit.
if (strcmp(Serverbuf, "quit") == 0){
if (send(acceptSock , "quit", strlen("quit"), 0) == SOCKET_ERROR){
printf("send \"quit\" failed\n");
}
break;
}
// or, send the same msg
else{
char msg[BUF_SIZE];
sprintf(msg, "Message recevied: %s\n", Serverbuf);
if (send(acceptSock, Serverbuf, BUF_SIZE, 0) == SOCKET_ERROR){
printf("Send failed!\n");
closesocket(listenSock);
closesocket(acceptSock);
WSACleanup();
exit(1);
}
}// end of if-else
}// end of while
// release all resource
closesocket(listenSock);
closesocket(acceptSock);
WSACleanup();
system("pause");
return 0;
}
// stdafx.h : 标准系统包含文件的包含文件,
// 或是经常使用但不常更改的
// 特定于项目的包含文件
//
#pragma once
#include "targetver.h"
#include <iostream>
#include <stdio.h>
#include <tchar.h>
#include <WinSock2.h>
#include <Windows.h>
#pragma comment (lib, "ws2_32.lib")
// TODO: 在此处引用程序需要的其他头文件
客户端代码
// P100_TcpClient.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#define BUF_SIZE 64
int _tmain(int argc, _TCHAR* argv[])
{
WSADATA wsaData;
SOCKET sHost;
SOCKADDR_IN servAddr; // 服务器IP
char buf[BUF_SIZE];
// 初始化Socket库
if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0){
printf("WSAStartup failed!\n");
WSACleanup();
exit(1);
}
// 创建Socket
if ((sHost = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET){
printf("socket failed!\n");
WSACleanup();
exit(1);
}
// 设置服务器地址
servAddr.sin_family = AF_INET;
servAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
// 假设的服务器地址,实际应用中服务器地址和端口号应该保存在配置文件中
servAddr.sin_port = htons(9990);
int sServAddrLen = sizeof(servAddr);
// link to server
if (connect(sHost, (LPSOCKADDR)&servAddr, sizeof(servAddr)) == SOCKET_ERROR){
printf("connect failed!\n");
printf("%d\n", WSAGetLastError());
closesocket(sHost);
WSACleanup();
exit(1);
}
// 循环向服务器发送数据
// quit命令退出与服务器连接,之后客户端自身退出
printf("已连接至服务器...\n\n");
while(true){
printf("Send: ");
std::string str;
std::getline(std::cin, str); // 从标准输入流中读取一行
ZeroMemory(buf, BUF_SIZE);
strcpy(buf,str.c_str()); // c_str()把字符串转为数组中存放的形式
if (send(sHost, buf, strlen(buf), 0) == SOCKET_ERROR){
printf("send failed!\n");
closesocket(sHost);
WSACleanup();
exit(1);
}
// 接受服务器传回的消息
if (recv(sHost, buf, sizeof(buf)+1, 0) == SOCKET_ERROR){
printf("recv failed!\n");
closesocket(sHost);
WSACleanup();
exit(1);
}
printf("Recv: %s\n", buf);
// 若收到quit,则退出
if (strcmp(buf, "quit") == 0){
printf("quit!\n");
break;
}
}// end of while
// release all resource
closesocket(sHost);
WSACleanup();
system("pause");
return 0;
}
// stdafx.h : 标准系统包含文件的包含文件,
// 或是经常使用但不常更改的
// 特定于项目的包含文件
//
#pragma once
#include "targetver.h"
#include <stdio.h>
#include <tchar.h>
#include <WinSock2.h>
#include <iostream>
#include <string>
#pragma comment (lib,"WS2_32.lib")
// TODO: 在此处引用程序需要的其他头文件