windows多客户端与liunx-ubuntu服务端进行通信

1 篇文章 0 订阅

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;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值