客戶端,服務端

陈若麟發表於2024-06-08
//客戶端 
#include"mysocket.h"
//標頭檔案 
using namespace std;
 
int main()
{
	cout << "-----------------客戶端----------------\n";
	startup();				//啟動 
	//檢測版本號
	if (LOBYTE(wsdata.wVersion) != 2 || HIBYTE(wsdata.wHighVersion) != 2) {
		cout << "版本號與服務端不匹配!" << endl;
		WSACleanup();
		return FALSE;
	}
	//填充服務端資訊:這裡填和服務端一樣的就好,不做解釋 
	SOCKET client = createSocket(PF_INET, SOCK_STREAM);
	SOCKADDR_IN server_addr;
	server_addr.sin_family = AF_INET;
	server_addr.sin_addr.S_un.S_addr = inet_addr("192.168.1.49");
	server_addr.sin_port = htons(8226);
	//傳送連線請求 請求連線伺服器
	if (connect(client, (SOCKADDR*)&server_addr, sizeof(SOCKADDR)) == SOCKET_ERROR) {
		cout << "連線錯誤!" << endl;
		WSACleanup();
		return -1;
	}
	cout << "成功連線到伺服器" << endl;
	char send_buf[1145], recv_buf[4514];
	while(100){
		cout << "輸入要傳送的資訊:";
		cin>>send_buf;
		mysend(client, send_buf);
		cout << "等待服務端響應...\n";
		myrecv(client, recv_buf);
		cout << "收到來自服務端的資訊:" << recv_buf << endl;
	}
	return 0;
}

  

//服務端(以C++作範例)
#include"mysocket.h"		
//匯入標頭檔案:由於mysock標頭檔案本身就有其它檔案,這裡無需匯入 	
using namespace std;
 
SOCKET s_accept;
 
int main()
{
	cout << "---------------------------服務端---------------------------\n";
	cout << "正在啟動...\n";
	startup();
	cout << "啟動成功!\n";
	SOCKET s = createSocket(PF_INET, SOCK_STREAM);
	//以IPV6協議建立套接字 
	//填充資訊 
	SOCKADDR_IN server_addr;
	server_addr.sin_family = AF_INET;//協議 
	server_addr.sin_port = htons(8226);//埠,隨便填 
	server_addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); 
	//ip地址,這裡填服務端裝置上的ip,127.0.0.1是本地ip,不能實現跨裝置互動 
	if (bind(s, (SOCKADDR*)&server_addr, sizeof(SOCKADDR)) == SOCKET_ERROR)
	//繫結套接字 
	{
		cout << "套接字繫結失敗!\n";
		WSACleanup();
		return FALSE;
	}
	cout << "套接字繫結成功!" << endl;
	if (listen(s, 1) == SOCKET_ERROR)
	{
		//監聽:將服務端轉為被動狀態,接收請求 
		cout << "監聽失敗!\n";
		WSACleanup();
		return FALSE;
	}
	cout << "設定監聽狀態成功!\n";
	sockaddr_in accept_addr;         //用來記錄請求連線的套接字資訊
	int len = sizeof(SOCKADDR);
	cout << "等待客戶端發起請求..." << endl;
	SOCKET t = accept(s, (SOCKADDR*)&accept_addr, &len);
	//接受連線請求 
	if (s_accept == SOCKET_ERROR) {
		cout << "請求錯誤!\n";
		WSACleanup();
		return FALSE;
	}
	cout << "建立連線成功!\n";
	char recv_buf[1145], send_buf[4514];
	while(1){
		//資訊互動部分,可以作改動 
		myrecv(t, recv_buf);
		cout << "接收到客戶端資訊:" << recv_buf << endl;
		cout << "請輸入要傳送的資訊:";
		cin >> send_buf;
		mysend(t, send_buf);
	}
    return 0;
}

  

//mysocket.h
#ifndef __MYSOCKET_H__
#define __MYSOCKET_H__
//標頭檔案保護 
#include<bits/stdc++.h>
#include<winsock.h>
#pragma comment(lib,"ws2_32.lib")
 
using namespace std;
 
WSADATA wsdata;
 
void startup(){
	//非同步啟動 
	if (WSAStartup(MAKEWORD(2, 2), &wsdata))
	/*	               ^                ^ 
			    版本號,這裡用的是2.2   |
			    			資料存放處,這裡設成全域性變數 
	*/ 
	{
		//返回0則成功,否則失敗,報錯 
		cout << "啟動失敗!\n";
		WSACleanup();
		exit(0);
	}
}
 
SOCKET createSocket(int af, int type){
	/*原函式原型: 
	  SOCKET socket(int af, int type, int protocol)
	  				    ^       ^           ^
	  			      協議  型別(後文) 形式(一般用0) 
	*/
	SOCKET ret = socket(af, type, 0);
	if (ret == INVALID_SOCKET)  //錯誤返回INVALID_SOCKET 
	{
		//報錯 
		cout << "建立套接字失敗!\n";
		WSACleanup();
		exit(0);
	}
	return ret;
}
 
void mysend(SOCKET s, const char* buf){
	/*
		帶報錯的send()函式,原函式原型為 :
		int send(SOCKET s, const char* buf, int len, int flag) 
		這裡為了簡化,省略後兩個引數。 
		函式把buf傳送給s,返回傳送長度 
	*/ 
	int len = send(s, buf, sizeof(buf), 0);
	if(len < 0)		//傳送錯誤 
	{
		cout << "資訊傳送失敗!\n";
		WSACleanup();
		exit(0);
	}
}
 
void myrecv(SOCKET s, char* buf){
	/*
		帶報錯的recv()函式,其原型為: 
		int recv(SOCKET s, char* buf, int len, int flag)
		同樣省略後兩個引數 
		函式將從s收到的資訊儲存在buf中,返回接收長度 
	*/
	int len = recv(s, buf, sizeof(buf), 0);
	if(len < 0)
	{
		cout << "資訊接收失敗!\n";
		WSACleanup();
		exit(0);
	}
}
 
#endif
//別忘了 

  

在聯結器命令列加入
 -lwsock32

  

相關文章