我只是一个小白,自己第一次动手写的基于win32控制台的socket通信程序,同时程序代码也只适合与初学者,写的不好的地方也多多包涵(同时希望大佬多多指教),我也希望我分享的成果供给有需要的小白,希望能帮助到你们。
成果展示:
客户端核心代码:
void chatClient() {
//请求协议版本
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
if (LOBYTE(wsaData.wVersion) != 2 ||
HIBYTE(wsaData.wVersion) != 2) {
gotoXY(4, 8);
printf("请求协议版本失败");
}
else {
gotoXY(4, 8);
printf("请求协议版本成功");
}
//创建socket套接字
clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (clientSocket == INVALID_SOCKET) {
gotoXY(4, 9);
printf("套接字创建失败");
WSACleanup();
}
else
{
gotoXY(4, 9);
printf("套接字创建成功");
}
//创建协议族
SOCKADDR_IN addrConServer;
addrConServer.sin_family = AF_INET;
addrConServer.sin_addr.S_un.S_addr = inet_addr(IP_ADDR);
addrConServer.sin_port = htons(LISTEN_PORT);
//向服务器发出请求连接
int len = sizeof(SOCKADDR);
if (connect(clientSocket, (sockaddr*)&addrConServer, len) == SOCKET_ERROR) {
gotoXY(4, 10);
printf("连接失败:%d", WSAGetLastError());
closesocket(clientSocket);
WSACleanup();
}
else
{
gotoXY(4, 10);
printf("连接成功");
}
//数据通信以及线程
char ch[1024];
while (1) {
memset(ch, 0, 1024);
gotoXY(4, 11 + var_b);
//清楚遗留的文字
printf(" ");
gotoXY(4, 11 + var_b);
printf(">>");
scanf_s("%s", ch);
send(clientSocket, ch, strlen(ch), NULL);
var_b++;
if (var_b == 16) {
var_b = 0;
}
}
//
}
服务器端核心代码:
void chatServer() {
//请求协议版本
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
if (LOBYTE(wsaData.wVersion) != 2 ||
HIBYTE(wsaData.wVersion) != 2) {
gotoXY(10, 13);
printf("请求协议失败");
}
else {
gotoXY(10, 13);
printf("请求协议版本成功");
}
//创建Socket套件字
SOCKET serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (serverSocket == INVALID_SOCKET)
{
gotoXY(10, 14);
printf("socket套键字创建失败");
WSACleanup();
}
gotoXY(10, 14);
printf("socket套键字创建成功");
//协议族创建
SOCKADDR_IN addr = { 0 };
addr.sin_family = AF_INET;
addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
addr.sin_port = htons(LISTEN_PORT);
//绑定
int len = sizeof(SOCKADDR);
int r = bind(serverSocket, (SOCKADDR*)&addr, len);
if (r == SOCKET_ERROR) {
gotoXY(10, 15);
printf("bind绑定失败");
closesocket(serverSocket);
}
gotoXY(10, 15);
printf("bind绑定成功");
//监听客户端请求
r = listen(serverSocket, 5);
if (r == SOCKET_ERROR) {
gotoXY(10, 16);
printf("监听失败");
closesocket(serverSocket);
}
gotoXY(10, 16);
printf("监听成功");
gotoXY(10, 17);
printf("连接中......");
//等待客户请求
while (1) {
//memset(buff, 0, 1024);
revSocket[count] = accept(serverSocket, (SOCKADDR*)&revAddr, &lengt);
if (revSocket[count] == INVALID_SOCKET) {
gotoXY(10, 17);
printf("客户端发出请求,服务器接收请求失败:");
closesocket(serverSocket);
WSACleanup();
}
else
{
gotoXY(10, 17);
printf("客户端发出请求,服务器接收请求成功");
gotoXY(22, 7);
printf("IP地址:%s", inet_ntoa(revAddr.sin_addr));
gotoXY(44, 7);
printf("对方端口:%d", ntohs(revAddr.sin_port));
gotoXY(10, 18);
CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)threadFunction, (char *)count, NULL, NULL);
count++;
//ExitThread(0);
}
}
closesocket(serverSocket);
WSACleanup();
/*char ch[1024];
while (1) {
memset(ch, 0, 1024);
//scanf("%s",ch);
r = recv(revSocket, ch, sizeof(ch), 0);
if (r > 0) {
ch[r] = 0;
gotoXY(10, 18 + var_b);
printf("客户端发送的数据: %s", ch);
}
else if (r == 0) {
gotoXY(10, 18 + var_b);
printf("Connection closed");
}
else {
gotoXY(10, 18 + var_b);
printf("recv failed: %d", WSAGetLastError());
}
var_b++;
if (var_b == 7) {
var_b = 0;
}
}*/
}
客户端完整代码:
#include<WinSock2.h>
#include<graphics.h>
#include<Windows.h>
#include<stdio.h>
#include<conio.h>
#pragma comment(lib,"ws2_32.lib")
#define DESIGN "※"
#define HEIGHT 7
#define TOTAL_HEIGHT 27
#define LISTEN_PORT 8888
#define IP_ADDR "127.0.0.1"
//全局变量
HANDLE handle_Out;
int var_b = 0;
//函数声明
void gotoXY(int, int);//辅助函数声明
void createTitleBorder();//画标题框声明
void socketTitle();//标题声明
void chatBorder();//聊天区声明
void rClientDorder();//客户端边框声明
void clientTitle();//客户端标题
void chatClient();//聊天
/*************************************************************第二次变量声明*****************************************************************/
SOCKET clientSocket;
HWND hwnd;
int count = 0;
/*************************************************************第二次变量声明*****************************************************************/
/**********************************************************************第二次调整区************************************************************/
//创建一个线程接收客户端的消息
void recvServerMessage() {
TCHAR recvBuff[1024];
int recvData;
//memset(recvBuff, 0, 1024);
while (1) {
memset(recvBuff, 0, 1024);
recvData = recv(clientSocket, recvBuff, 1023, NULL);
if (recvData > 0) {
recvBuff[recvData] = 0;
outtextxy(0, count * 20, recvBuff);
count++;
if (count == 16) {
cleardevice();
count = 0;
}
}
}
closesocket(clientSocket);
WSACleanup();
}
/**********************************************************************第二次调整区************************************************************/
//客户端标题
void clientTitle() {
gotoXY(80, 10);
printf("客");
gotoXY(80, 12);
printf("户");
gotoXY(80, 14);
printf("端");
gotoXY(0, 27);
}
//客户端
void rClientDorder() {
//上边框
for (int i = 70; i <= 90; i++) {
gotoXY(i, 0);
printf(DESIGN);
}
//上边框
for (int i = 70; i <= 90; i++) {
gotoXY(i, TOTAL_HEIGHT);
printf(DESIGN);
}
//左边框
for (int i = 0; i <= TOTAL_HEIGHT; i++) {
gotoXY(70, i);
printf(DESIGN);
}
//右边框
for (int i = 0; i <= TOTAL_HEIGHT; i++) {
gotoXY(92, i);
printf(DESIGN);
}
}
//聊天框
void chatBorder() {
//上边框
for (int i = 0; i <= 65; i++) {
gotoXY(i, HEIGHT);
printf(DESIGN);
}
//下边框
for (int i = 0; i <= 65; i++) {
gotoXY(i, HEIGHT + 20);
printf(DESIGN);
}
//左边框
for (int i = 0; i <= 20; i++) {
gotoXY(0, HEIGHT + i);
printf(DESIGN);
}
//右边框
for (int i = 0; i <= 20; i++) {
gotoXY(66, HEIGHT + i);
printf(DESIGN);
}
//gotoXY(0, 30);
}
//聊天
void chatClient() {
//请求协议版本
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
if (LOBYTE(wsaData.wVersion) != 2 ||
HIBYTE(wsaData.wVersion) != 2) {
gotoXY(4, 8);
printf("请求协议版本失败");
}
else {
gotoXY(4, 8);
printf("请求协议版本成功");
}
//创建socket套接字
clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (clientSocket == INVALID_SOCKET) {
gotoXY(4, 9);
printf("套接字创建失败");
WSACleanup();
}
else
{
gotoXY(4, 9);
printf("套接字创建成功");
}
//创建协议族
SOCKADDR_IN addrConServer;
addrConServer.sin_family = AF_INET;
addrConServer.sin_addr.S_un.S_addr = inet_addr(IP_ADDR);
addrConServer.sin_port = htons(LISTEN_PORT);
//向服务器发出请求连接
int len = sizeof(SOCKADDR);
if (connect(clientSocket, (sockaddr*)&addrConServer, len) == SOCKET_ERROR) {
gotoXY(4, 10);
printf("连接失败:%d", WSAGetLastError());
closesocket(clientSocket);
WSACleanup();
}
else
{
gotoXY(4, 10);
printf("连接成功");
}
//数据通信以及线程
char ch[1024];
while (1) {
memset(ch, 0, 1024);
gotoXY(4, 11 + var_b);
//清楚遗留的文字
printf(" ");
gotoXY(4, 11 + var_b);
printf(">>");
scanf_s("%s", ch);
send(clientSocket, ch, strlen(ch), NULL);
var_b++;
if (var_b == 16) {
var_b = 0;
}
}
//
}
//标题
void socketTitle() {
gotoXY(43, 2);
printf("Socket网络通信");
gotoXY(0, 30);
}
//画标题边框
void createTitleBorder() {
//画上边框
for (int i = 35; i < 65; i++) {
gotoXY(i, 0);
printf(DESIGN);
}
//画下边框
for (int i = 35; i < 65; i++) {
gotoXY(i, 5);
printf(DESIGN);
}
//画左边框
for (int i = 0; i <= 5; i++) {
gotoXY(35, i);
printf(DESIGN);
}
//画右边框
for (int i = 0; i <= 5; i++) {
gotoXY(65, i);
printf(DESIGN);
}
}
//辅助函数
void gotoXY(int x, int y) {
COORD pos = { x,y };
handle_Out = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(handle_Out, pos);
}
int main() {
TCHAR szTitle[] = "Client客户端";
TCHAR sTitle[] = "客户端输出框";
system("mode con cols=95 lines=28");
//system("color 2f");
SetWindowLong(FindWindow("ConsoleWindowClass", NULL), GWL_STYLE, GetWindowLong(FindWindow("ConsoleWindowClass", NULL), GWL_STYLE) & ~WS_SIZEBOX & ~WS_MAXIMIZEBOX & ~WS_MINIMIZEBOX);
hwnd = initgraph(256, 300, SHOWCONSOLE);
SetWindowText(hwnd, sTitle);
SetConsoleTitle(szTitle);
//创建标题 边框
createTitleBorder();
//标题
socketTitle();
//客户端
rClientDorder();
//客户端标题
clientTitle();
//聊天框
chatBorder();
/**********************************************************************第二次调整区************************************************************/
//创建线程
CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)recvServerMessage, NULL, NULL, NULL);
/**********************************************************************第二次调整区************************************************************/
//聊天
chatClient();
// 关闭句柄
ExitThread(0);
CloseHandle(handle_Out);
return 0;
}
服务器端完整代码:
#include<WinSock2.h>
#include<Windows.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<conio.h>
#pragma comment(lib,"ws2_32.lib")
#define TOTAL_HEIGHT 27
#define DESIGN "※"
#define LISTEN_PORT 8888
#define IP_ADDR "192.168.1.100"
/***************************************************************函数声明区域**********************************************************************************************/
void listenBorder();//接听框声明
void ipBoder();// ip框声明
void portBorder();//端口框声明
void showBorderInfo();//信息显示
void gotoXY(int, int);//辅助函数声明
void titleShow();//文字
void serverBorder();//客户端边框
void chatServer();//通信函数
void threadFunction(int id);//多线程
/***************************************************************函数声明区域**********************************************************************************************/
//
/***************************************************************全局变量区域**********************************************************************************************/
//全局变量
HANDLE handle_Out;
int var_b = 0;
SOCKET revSocket[1024];
int count = 0;
SOCKADDR_IN revAddr = { 0 };
int lengt = sizeof(SOCKADDR);
/***************************************************************全局变量区域**********************************************************************************************/
//
/***************************************************************WIN32控制台程序修饰窗口和数据输出区域**********************************************************************************************/
//客户端边框
void serverBorder() {
//上边框
for (int i = 70; i <= 90; i++) {
gotoXY(i, 0);
printf(DESIGN);
}
//上边框
for (int i = 70; i <= 90; i++) {
gotoXY(i, TOTAL_HEIGHT);
printf(DESIGN);
}
//左边框
for (int i = 0; i <= TOTAL_HEIGHT; i++) {
gotoXY(70, i);
printf(DESIGN);
}
//右边框
for (int i = 0; i <= TOTAL_HEIGHT; i++) {
gotoXY(92, i);
printf(DESIGN);
}
gotoXY(80, 10);
printf("服");
gotoXY(80, 12);
printf("务");
gotoXY(80, 14);
printf("器");
gotoXY(80, 16);
printf("端");
gotoXY(0, 28);
}
//接听框
void listenBorder() {
//下边框
for (int i = 8; i <= 16; i++) {
gotoXY(i, 8);
printf(DESIGN);
}
titleShow();
gotoXY(0, 28);
}
void titleShow() {
gotoXY(9, 7);
printf("开始监听");
}
// ip框声明
void ipBoder() {
//下边框
for (int i = 20; i <= 40; i++) {
gotoXY(i, 8);
printf(DESIGN);
}
gotoXY(0, 28);
}
//端口框声明
void portBorder() {
for (int i = 44; i <= 57; i++) {
gotoXY(i, 8);
printf(DESIGN);
}
gotoXY(0, 28);
}
//信息显示
void showBorderInfo() {
for (int i = 0; i <= 58; i++) {
gotoXY(i, 10);
printf(DESIGN);
}
//上边框
for (int i = 8; i <= 58; i++) {
gotoXY(i, 12);
printf(DESIGN);
}
//下边框
for (int i = 8; i <= 58; i++) {
gotoXY(i, 29);
printf(DESIGN);
}
//左边框
for (int i = 0; i <= 17; i++) {
gotoXY(8, 12 + i);
printf(DESIGN);
}
//右边框
for (int i = 0; i <= 17; i++) {
gotoXY(58, 12 + i);
printf(DESIGN);
}
//gotoXY(0, 28);
}
//辅助函数
void gotoXY(int x, int y) {
COORD pos = { x,y };
handle_Out = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(handle_Out, pos);
}
/***************************************************************WIN32控制台程序修饰窗口和数据输出区域**********************************************************************************************/
//
/***************************************************************Socket网络通信区域**********************************************************************************************/
//通信函数
void chatServer() {
//请求协议版本
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
if (LOBYTE(wsaData.wVersion) != 2 ||
HIBYTE(wsaData.wVersion) != 2) {
gotoXY(10, 13);
printf("请求协议失败");
}
else {
gotoXY(10, 13);
printf("请求协议版本成功");
}
//创建Socket套件字
SOCKET serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (serverSocket == INVALID_SOCKET)
{
gotoXY(10, 14);
printf("socket套键字创建失败");
WSACleanup();
}
gotoXY(10, 14);
printf("socket套键字创建成功");
//协议族创建
SOCKADDR_IN addr = { 0 };
addr.sin_family = AF_INET;
addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
addr.sin_port = htons(LISTEN_PORT);
//绑定
int len = sizeof(SOCKADDR);
int r = bind(serverSocket, (SOCKADDR*)&addr, len);
if (r == SOCKET_ERROR) {
gotoXY(10, 15);
printf("bind绑定失败");
closesocket(serverSocket);
}
gotoXY(10, 15);
printf("bind绑定成功");
//监听客户端请求
r = listen(serverSocket, 5);
if (r == SOCKET_ERROR) {
gotoXY(10, 16);
printf("监听失败");
closesocket(serverSocket);
}
gotoXY(10, 16);
printf("监听成功");
gotoXY(10, 17);
printf("连接中......");
//等待客户请求
while (1) {
//memset(buff, 0, 1024);
revSocket[count] = accept(serverSocket, (SOCKADDR*)&revAddr, &lengt);
if (revSocket[count] == INVALID_SOCKET) {
gotoXY(10, 17);
printf("客户端发出请求,服务器接收请求失败:");
closesocket(serverSocket);
WSACleanup();
}
else
{
gotoXY(10, 17);
printf("客户端发出请求,服务器接收请求成功");
gotoXY(22, 7);
printf("IP地址:%s", inet_ntoa(revAddr.sin_addr));
gotoXY(44, 7);
printf("对方端口:%d", ntohs(revAddr.sin_port));
gotoXY(10, 18);
CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)threadFunction, (char *)count, NULL, NULL);
count++;
//ExitThread(0);
}
}
closesocket(serverSocket);
WSACleanup();
/*char ch[1024];
while (1) {
memset(ch, 0, 1024);
//scanf("%s",ch);
r = recv(revSocket, ch, sizeof(ch), 0);
if (r > 0) {
ch[r] = 0;
gotoXY(10, 18 + var_b);
printf("客户端发送的数据: %s", ch);
}
else if (r == 0) {
gotoXY(10, 18 + var_b);
printf("Connection closed");
}
else {
gotoXY(10, 18 + var_b);
printf("recv failed: %d", WSAGetLastError());
}
var_b++;
if (var_b == 7) {
var_b = 0;
}
}*/
}
/***************************************************************Socket网络通信区域**********************************************************************************************/
//
/***************************************************************多线程调用**********************************************************************************************/
void threadFunction(int id) {
TCHAR buff[1024];
char buff1[1024];
int re;
while (1){
memset(buff, 0, 1024);
re = recv(revSocket[id], buff, 1023, NULL);
if (re > 0) {
buff[re] = 0;
//清楚遗留的文字
gotoXY(10, 18 + var_b);
printf(" ");
gotoXY(10, 18 + var_b);
printf("<%d>号客户端发送的数据: %s",id+1, buff);
for (int i = 0; i < count; i++) {
send(revSocket[i], buff, 1023, NULL);
}
}
else if (re == 0) {
gotoXY(10, 18 + var_b);
printf("Connection closed");
closesocket(revSocket[id]);
WSACleanup();
}
else {
gotoXY(10, 18 + var_b);
printf("recv failed: %d", WSAGetLastError());
closesocket(revSocket[id]);
WSACleanup();
continue;
}
//memset(buff, 0, 1024);
var_b++;
if (var_b == 11) {
var_b = 0;
}
};
}
/***************************************************************多线程调用**********************************************************************************************/
/
int main(){
TCHAR szTitle[] = "Server服务器";
system("mode con cols=96 lines=30");
//system("color 2f");
SetWindowLong(FindWindow("ConsoleWindowClass", NULL), GWL_STYLE, GetWindowLong(FindWindow("ConsoleWindowClass", NULL), GWL_STYLE) & ~WS_SIZEBOX & ~WS_MAXIMIZEBOX & ~WS_MINIMIZEBOX);
SetConsoleTitle(szTitle);
//接听
listenBorder();
//ip框
ipBoder();
//端口
portBorder();
//客户端
serverBorder();
//信息显示
showBorderInfo();
//通信函数
chatServer();
//关闭句柄
CloseHandle(handle_Out);
return 0;
}