我只是一個小白,自己第一次動手寫的基于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;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/380216.html
標籤:其他
