socket多人聊天

2021-10-01 14:58:13 字數 4444 閱讀 4423

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...