Windows下的網絡編程

基礎教程
https://www.cnblogs.com/lgh1992314/p/6616393.html
各種函數
https://blog.csdn.net/qq_43152052/article/details/93179297
Dev C++調整
連接器附加: -lwsock32
編譯器附加:-std=c++11 -lpthread
代碼:
server.cpp

#include <thread>
#include<iostream>
#include<Winsock2.h>
#include<stdio.h>
#pragma comment(lib, "ws2_32.lib")
using namespace std;
int len;
SOCKET sockServer;     // 服務端 Socket
SOCKADDR_IN addrServer;// 服務端地址
SOCKET sockClient[5];     // 客戶端 Scoket
SOCKADDR_IN addrClient;// 客戶端地址
WSADATA wsaData;       // winsock 結構體
WORD wVersionRequested;// winsock 的版本
char sendBuf[5][100]; // 發送至客戶端的字符串0
char recvBuf[5][100]; // 接受客戶端返回的字符串
void fors(int i){
	while(1){
		// accept 會阻塞進程,直到有客戶端連接上來爲止
		sockClient[i] = accept(sockServer, (SOCKADDR *)&addrClient, &len);
		// 當客戶端連接上來時, 拼接如下字符串
		sprintf(sendBuf[i],"鏈接成功\n",inet_ntoa(addrClient.sin_addr));
		cout<<"<#"<<i<<" join "<<inet_ntoa(addrClient.sin_addr) <<">"<<""<<endl;
		// 向客戶端發送字符串
		send(sockClient[i],sendBuf[i], strlen(sendBuf[i]) + 10, 0);
		while(1){
			
			// 獲取客戶端返回的數據
			int error=recv(sockClient[i],recvBuf[i], 100, 0);
			if(error==-1) {
				cout<<"<#"<<i<<" Exit "<<inet_ntoa(addrClient.sin_addr)<<">"<<endl;
				break;
			}//獲取數據失敗 
			// 打印客戶端返回的數據
			cout<<"<#"<<i<<" Message "<<inet_ntoa(addrClient.sin_addr)<<"> "<<recvBuf[i]<<endl;
		}
		// 關閉socket
		closesocket(sockClient[i]);
	}
}
int got(){
	char buf[110];
	while(1){
		scanf("%s",buf);
		if(strcmp(buf,"stop")==0){
			exit(0);
		}
	}
}
int main()
{
	// 配置 Windows Socket版本
	wVersionRequested=MAKEWORD( 2, 2 );
	// 初始化 Windows Socket
	int err=WSAStartup( wVersionRequested, &wsaData );
	if(err!=0)// 啓動錯誤,程序結束
		return 0;
	if(LOBYTE(wsaData.wVersion) != 2 || HIBYTE( wsaData.wVersion ) != 2 ){// 啓動錯誤,程序結束
		WSACleanup();// 終止Winsock 2 DLL (Ws2_32.dll) 的使用
		return 0;
	}
	// 定義服務器端socket
	sockServer= socket(AF_INET, SOCK_STREAM, 0);
	//  設置服務端 socket
	addrServer.sin_addr.S_un.S_addr= htonl(INADDR_ANY); // 本機IP
	addrServer.sin_family= AF_INET;                   // 協議類型是INET
	addrServer.sin_port= htons(6000);                 // 綁定端口6000
	// 將服務器端socket綁定在本地端口
	bind(sockServer,(SOCKADDR *)&addrServer, sizeof(SOCKADDR));
	// Listen 監聽端口
	listen(sockServer,1); // 5 爲等待連接數目
	printf("Done!\n");
	len = sizeof(SOCKADDR);
	thread a(fors,0);
	thread ab(fors,1);
	thread ini(got);
	a.join();
	ab.join();
	ini.join();
	
}

cli.cpp

#include <Winsock2.h>
#include <thread>
#include <stdio.h>
#pragma comment(lib, "ws2_32.lib")
using namespace std;
int err;
char message[100];
char recvBuf[100];
SOCKET sockClient; // 客戶端 Scoket
SOCKADDR_IN addrServer; // 服務端地址
WSADATA wsaData;
WORD wVersionRequested;
void exits(){
	//關閉 
	closesocket(sockClient);
	WSACleanup();
}
void recs(){
	while(1){
		int err=recv(sockClient,recvBuf, 100, 0);
		if(err==-1) return ;
		// 打印數據
		printf("%s",recvBuf);
	}
}
void sends(){
	while(1){
		scanf("%s",message);
		// 發送數據到服務端
		err=send(sockClient, message, strlen(message) + 10, 0);
		if(err==-1) return ;
	}
	
}
int main() {
	atexit(exits);
	wVersionRequested = MAKEWORD( 2, 2 );
	err = WSAStartup( wVersionRequested, &wsaData );
	if(err != 0) {
		return 0;
	}
	if( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 ) {
		// 啓動錯誤,程序結束
		WSACleanup();
		return 0;
	}
	// 新建客戶端 scoket
	sockClient = socket(AF_INET, SOCK_STREAM, 0);
	// 定義要連接的服務端地址
	addrServer.sin_addr.S_un.S_addr= inet_addr("127.0.0.1");
// 目標IP (127.0.0.1是本機地址)
	addrServer.sin_family = AF_INET;                           // 協議類型是INET
	addrServer.sin_port = htons(6000);                         // 連接端口1234
	// 讓 sockClient 連接到 服務端
	int err=connect(sockClient,(SOCKADDR *)&addrServer, sizeof(SOCKADDR));
	if(err==-1) printf("exit"),exit(0);
	// 從服務端獲取數據
	thread rec(recs);thread se(sends);
	rec.join();se.join();
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章