日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

windows多客戶端與liunx-ubuntu服務端進行通信

作者:z_tt123456789 更新時間: 2022-07-18 編程語言

windows多客戶端與liunx-ubuntu服務端進行通信

liunx服務端:

#include <stdio.h>
#include <netinet/in.h>
#include <pthread.h>
#include <ctype.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <cstdlib>
#include <string>
#include <iostream>


#define MAXLINE 80
#define SERV_PORT 8000

//編譯的時候 因為thread不是內置的  要加上gcc main.c -o test -lpthread 
struct s_info {
        struct sockaddr_in cliaddr;
        int connfd;
};
void *do_work(void *arg)
{
        int n,i;
        struct s_info *ts = (struct s_info*)arg;
        char buf[MAXLINE];//在線程自己的用戶空間棧開辟的,該線程運行結束的時候,主
控線程就不能操作這塊內存了
        char str[INET_ADDRSTRLEN];//INET_ADDRSTRLEN 是宏16個字節

//在創建線程前設置線程創建屬性,設為分離態,效率高
        pthread_detach(pthread_self());

        while (1) {
        n = read(ts->connfd, buf, MAXLINE);
        if (n == 0) {
                printf("the other side has been closed.\n");
                break;
                }
        printf("received from %s at PORT %d\n",
        inet_ntop(AF_INET, &(*ts).cliaddr.sin_addr, str, sizeof(str)),ntohs((*ts).cliaddr.sin_port));

        for (i = 0; i < n; i++)
            buf[i] = toupper(buf[i]);
        write(ts->connfd, buf, n);
        }
        close(ts->connfd);
}
int main(void)
{
        struct sockaddr_in servaddr, cliaddr;
        socklen_t cliaddr_len;
        int listenfd, connfd;
        int i = 0;
        pthread_t tid;
        struct s_info ts[3497];

        listenfd = socket(AF_INET, SOCK_STREAM, 0);
        bzero(&servaddr, sizeof(servaddr));
        servaddr.sin_family = AF_INET;
        servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
        servaddr.sin_port = htons(SERV_PORT);

        bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
        listen(listenfd, 20);

        printf("Accepting connections ...\n");
        while (1) {
                cliaddr_len = sizeof(cliaddr);
                connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &cliaddr_len);
                ts[i].cliaddr = cliaddr;
                ts[i].connfd = connfd;
/* 達到線程最大數時,pthread_create出錯處理, 增加服務器穩定性 */
                pthread_create(&tid, NULL, do_work, (void*)&ts[i]);//把accept得>到的客戶端信息傳給線程,讓線程去和客戶端進行數據的收發
                i++;
        }
return 0;
}

windows客戶端---在vs2017上面運行多個客戶端連接同一個服務端通信

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <Windows.h>
#include <iostream>
#include <string>
using namespace std;
#pragma comment(lib, "ws2_32.lib")
#define Port 8000//8866  8866單項連接 和服務端通信 server 互相通信
#define IP_ADDRESS "192.168.223.128"     //服務器地址 在服務端通過ifconfig -a查看服務端的ip地址

#define MaxBufSize 1024

//監聽服務器消息
DWORD WINAPI recvFromServer(LPVOID lpParam)
{
	char buf[MaxBufSize];
	SOCKET *ClientSocket = (SOCKET*)lpParam;
	while (1)
	{
		memset(buf, '\0', sizeof(buf));
		if (recv(*ClientSocket, buf, 1024, 0) <= 0)
		{
			printf("close\n");
			break;
			closesocket(*ClientSocket);
		}
		printf("%s\n", buf);
	}
	return 0;
}


int main() // argc是命令行總的參數個數
{	
	WSADATA s; // 用來儲存調用AfxSocketInit全局函數返回的Windows Sockets初始化信息
	SOCKET ClientSocket;
	struct sockaddr_in ClientAddr; // 一個sockaddr_in型的結構體對象
	int ret = 0;
	char SendBuffer[MAX_PATH]; // Windows的MAX_PATH默認是260

	// 初始化Windows Socket
	// WSAStartup函數對Winsock服務的初始化
	if (WSAStartup(MAKEWORD(2, 2), &s) != 0) // 通過連接兩個給定的無符號參數,首個參數為低字節
	{
		printf("Init Windows Socket Failed! Error: %d\n", GetLastError());
		getchar();
		return -1;
	}
	while (1)
	{
		// 創建一個套接口
		// 如果這樣一個套接口用connect()與一個指定端口連接
		// 則可用send()和recv()與該端口進行數據報的發送與接收
		// 當會話結束后,調用closesocket()
		ClientSocket = socket(AF_INET, // 只支持ARPA Internet地址格式
			SOCK_STREAM, // 新套接口的類型描述
			IPPROTO_TCP); // 套接口所用的協議
		if (ClientSocket == INVALID_SOCKET)
		{
			printf("Create Socket Failed! Error: %d\n", GetLastError());
			getchar();
			return -1;
		}
		ClientAddr.sin_family = AF_INET;
		ClientAddr.sin_addr.s_addr = inet_addr(IP_ADDRESS); // 定義IP地址
		ClientAddr.sin_port = htons(Port); // 將主機的無符號短整形數轉換成網絡字節順序
		memset(ClientAddr.sin_zero, 0X00, 8); // 函數通常為新申請的內存做初始化工作
		// 連接Socket
		ret = connect(ClientSocket,
			(struct sockaddr*)&ClientAddr,
			sizeof(ClientAddr));
		if (ret == SOCKET_ERROR)
		{
			printf("Socket Connect Failed! Error:%d\n", GetLastError());
			getchar();
			return -1;
		}
		else
		{
			printf("Socket Connect Succeed!");
		}
		printf("Input Data: ");
		//創建線程  發送消息
		//CreateThread(NULL, 0, &recvFromServer, &ClientSocket, 0, NULL);
		//char info[1024], SendBuffer[MaxBufSize], RecvBuff[MaxBufSize];
		
		while (1)
		{//多客戶端和服務端通信   服務端為dserver
			scanf("%s", &SendBuffer);
			send(ClientSocket, SendBuffer, (int)strlen(SendBuffer), 0);
			int recvLen = recv(ClientSocket, SendBuffer, MaxBufSize, 0);
			if(recvLen == 0) printf("Message form server:\n");
			else printf("Message form server: %s\n", SendBuffer);
			// 發送數據至服務器
			//ret = send(ClientSocket,
			//	SendBuffer,
			//	(int)strlen(SendBuffer), // 返回發送緩沖區數據長度
			//	0);
			//if (ret == SOCKET_ERROR)
			//{
			//	printf("Send Information Failed! Error:%d\n", GetLastError());
			//	getchar();
			//	break;
			//}
			接收服務端發的消息
			//char bufRecv[MaxBufSize] = { 0 };
			//int recvLen = recv(ClientSocket, bufRecv, MaxBufSize, 0);
			//printf("Message form server: %s\n", bufRecv);
			Sleep(500);
			memset(RecvBuff, 0, sizeof(RecvBuff));
			break;
		}
		// 關閉socket
		closesocket(ClientSocket);
		if (SendBuffer[0] == 'q') // 設定輸入第一個字符為q時退出
		{
			printf("Quit!\n");
			break;
		}
	}
	WSACleanup();
	getchar();
	system("pause");
	return 0;
}

原文鏈接:https://blog.csdn.net/z_tt123456789/article/details/108383794

欄目分類
最近更新