網站首頁 編程語言 正文
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
相關推薦
- 2022-09-05 Redis 數據刪除策略
- 2022-01-20 Syntax Error: TypeError: this.getOptions is not a
- 2022-08-31 Linux環境下安裝python3_python
- 2024-07-15 Redis 底層數據結構-簡單動態字符串(SDS)
- 2022-06-22 使用pyinstaller打包.exe文件的詳細教程_python
- 2022-07-25 pandas實現數據讀取&清洗&分析的項目實踐_python
- 2023-12-26 錯誤代碼: 1062Duplicate entry ‘304‘ for key ‘tb_clue_t
- 2022-11-05 一篇文章說清楚?go?get?使用私有庫的方法_Golang
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支