ide:vs2019
client連線server
client發訊息給server
server**給其他的client
主要用select
wrap.h
#pragma once
#include#includeusing namespace std;
void init_wsa()
//檢查socket版本
if (lobyte(wsa_data.wversion) != 2 ||
hibyte(wsa_data.wversion) != 2)
}int closesocket(socket& s)
return 0;
}socket accept(socket& s, sockaddr* addr, int* addrlen)
cout << "connect error" << wsagetlasterror() << endl;
closesocket(s);
wsacleanup();
exit(-1);
} return cfd;
} cout << "connect error" << wsagetlasterror() << endl;
closesocket(s);
wsacleanup();
exit(-1);
}int bind(socket& s, const sockaddr* name, int namelen)
return result;
}socket socket(int af, int type, int protocol)
return lfd;
}int listen(socket& fd, int backlog)
return result;
}int connect(socket& s, const sockaddr* name, int namelen)
return result;
}int recv(socket& s, char* buf, int len, int flags)
return socket_error;
} return receive_len;
} return socket_error;
}int send(socket& s, const char* buf, int len, int flags)
return socket_error;
} return 0;
} return 0;
}
client
#include#include#include#include#include#include#pragma comment(lib,"ws2_32.lib")
#include "wrap.h"
using namespace std;
mutex _mutex;
/* * 接收資料
* @param cfd 檔案描述符
*/void receive(socket& cfd) //斷開連線
else if (0 == receive_len)
else
} closesocket(cfd);
wsacleanup();
exit(0);
}int main() ;
server_addr.sin_family = af_inet;
server_addr.sin_port = htons(server_port);
inet_pton(af_inet, server_ip, &server_addr.sin_addr.s_un.s_addr);
//連線
connect(cfd, (sockaddr*)&server_addr, sizeof(server_addr));
cout << "建立連線" << endl;
//開執行緒接收資料
thread th(receive, ref(cfd));
th.detach();
string send_data;
while (true)
else if ("" == send_data)
//傳送資訊
if (socket_error == send(cfd, send_data.c_str(), static_cast(send_data.size()), 0))
} closesocket(cfd);
wsacleanup();
return 0;
}
server
#include#include#include#include#include#include#pragma comment(lib,"ws2_32.lib")
#include "wrap.h"
using namespace std;
int main() ;
server_addr.sin_family = af_inet;
server_addr.sin_port = htons(port);
server_addr.sin_addr.s_un.s_addr = htonl(inaddr_any);
//埠復用
bool boptval = false;
setsockopt(lfd, sol_socket, so_reuseaddr, (char*)&boptval, sizeof(boptval));
//繫結埠
bind(lfd, (sockaddr*)&server_addr, sizeof(server_addr));
//設定同時連線的上限
listen(lfd, somaxconn);
//連線過來的客戶端的檔案描述符(-1表示沒有連線)
socket client[fd_setsize];
string client_ip[fd_setsize];
memset(client, -1, sizeof(int) * fd_setsize);
//最大的檔案描述符
int max_fd = static_cast(lfd);
//檔案描述符在client陣列中最大的位置
int max_i = -1;
fd_set rset, all_set;
//初始化全0
fd_zero(&all_set);
fd_set(lfd, &all_set);
//客戶端
sockaddr_in client_addr;
//長度
socklen_t client_addr_len = sizeof(client_addr);
socket cfd;
cout << "等待連線" << endl;
while (true)
//lfd對應位置為1,說明有新連線,處理乙個
if (fd_isset(lfd, &rset) != 0)
//連線已經到達上線
if (i >= fd_setsize)
//記錄
client[i] = cfd;
client_ip[i].assign(inet_ntop(af_inet, &client_addr.sin_addr.s_un.s_addr, receive_data, bufsiz));
client_ip[i] += ":";
client_ip[i] += to_string(ntohs(client_addr.sin_port));
cout << "client ip: " << client_ip[i] << endl;
//向all_set新增檔案描述符cfd
fd_set(cfd, &all_set);
//更新
if (cfd > max_fd)
if (i > max_i)
--nready;
//沒有要處理的
if (0 == nready)
} for (int i = 0; i <= max_i; ++i)
if (fd_isset(cfd, &rset) != 0)
//客戶端關閉連線
else if (0 == receive_len)
else
//傳送錯誤
if (socket_error == send(send_fd, msg.c_str(), static_cast(msg.size()), 0)) }}
--nready;
if (0 == nready)
}} }
closesocket(lfd);
wsacleanup();
return 0;
}
Socket多人聊天MFC版
學習彙總 持續更新 從零搭建後端基礎設施系列 一 背景介紹 coding 環境 vs2015 win10 測試環境 vm虛擬機器 xp系統 2003server和主機win10 語言 c 類庫mfc 功能 基於伺服器 訊息的多人聊天。主要原理 server給每個連上的client都建立乙個執行緒單獨...
Linux下socket多人聊天室
四 功能模組流程圖 五 實驗截圖 六 問題及解決 七 參考文獻 附錄由於疫情原因,在家上了一學期的課,本次作業是作為 linux程式設計 的期末考核而布置的,代替了原本的線上答題考試,對於我這種比較喜歡動手的菜雞來說,還是很舒服的。1.服務端功能模組圖 圖3.1 服務端功能模組圖 服務端主要完成的工...
TCP傳輸 多人聊天
乙個簡單的多人聊天 服務端 1 用 serversocket 建立伺服器,指定埠 2 接收客戶端連線,阻塞式等待 3 連線好了之後,使用輸出流傳送資料到套接字 一塊公共區域 public class mytcpservice catch exception e 傳送資料執行緒 class mycha...