- C++: Use C++ language for programming, including using C++ standard library and related data types, functions, etc.
- Socket programming: Based on socket (Socket) network communication, the server is established by creating sockets, binding addresses, listening to connection requests, and accepting client connections.
- Linux environment: develop under the Linux operating system, use the corresponding system calls and header files.
- Network protocol: communicate based on TCP/IP protocol stack, use TCP protocol to achieve reliable data transmission
The actual network programming may also involve other advanced technologies and functions, such as multi-thread processing, non-blocking IO, asynchronous programming, network security, etc., which can be expanded and optimized according to the needs.
writing ideas
- Import the required header files:
-
#include <iostream> #include <sys/socket.h> #include <netinet/in.h>//网络通信TCP/IP协议 #include <unistd.h>
-
Create socket:
-
int sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd == -1) { std::cout << "Failed to create socket" << std::endl; return -1; }
-
Set server address and port:
-
sockaddr_in serverAddress{}; serverAddress.sin_family = AF_INET; serverAddress.sin_addr.s_addr = INADDR_ANY; serverAddress.sin_port = htons(port); // 设置端口号 if (bind(sockfd, (struct sockaddr*)&serverAddress, sizeof(serverAddress)) < 0) { std::cout << "Binding failed" << std::endl; return -1; }
-
Listen for connection requests:
-
if (listen(sockfd, backlog) < 0) { std::cout << "Listening failed" << std::endl; return -1; }
-
Accept client connections:
-
sockaddr_in clientAddress{}; socklen_t clientAddressLength = sizeof(clientAddress); int clientSocket = accept(sockfd, (struct sockaddr*)&clientAddress, &clientAddressLength); if (clientSocket < 0) { std::cout << "Accepting connection failed" << std::endl; return -1; }
-
Communicate with the client: In this step, code can be written according to specific needs to handle the communication with the client. Can be used
clientSocket
to send and receive data. -
Close the socket:
close(clientSocket); close(sockfd);
Please note that in a Linux environment, you may also need to add appropriate permissions and set firewall rules to ensure normal network connectivity .
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <pthread.h>
#include <arpa/inet.h>
#include <list>
using namespace std;
#define _PORT_ 2022
#define _BACKLOG_ 10
// 客服连接到服务器后,需要先登录,发送登录消息:
// name字符串,不能含有空格
struct client {
public:
int socket;
char name[32];
char ip[16];
bool operator==(const client &other) const {
return other.socket == socket;
}
};
list<client> clients;
void showClients() {
printf("\n\n***********show all clients********\n");
int k=0;
for(auto it=clients.begin(); it != clients.end(); it++) {
printf("NO.%d name:[%s] socket:[%d]\n", ++k, it->name, it->socket);
}
printf("\n*********************************** \n\n");
}
void* client_func(void *arg) {
client *p = (client*)arg;
// regist
char buf[1024];
char buff2[1024];
memset(buf,'0',sizeof(buf));//跟前面的初始化对比
if (read(p->socket, buf, sizeof(buf)) <= 0) {
delete p;
return NULL;
}
printf("Receive register info: %s\n",buf);
sscanf(buf, "%s", p->name);
sprintf(buf, "【%s@%s】进入聊天室", p->ip, p->name);
clients.push_back(*p);
printf("Add a new client. count=%d\n", clients.size());
//showClients();
printf("clients size = %d\n", clients.size());
int k=0;
for(auto it=clients.begin(); it != clients.end(); it++) {
printf("send no.%d client\n", ++k);
write(it->socket, buf, strlen(buf)+1);
}
//clients.push_back(*p);
while(1) {
int ret = read(p->socket, buf, sizeof(buf));
if (ret <= 0) {
break;
}
printf("client :# %s\n",buf);
sprintf(buff2, "【%s@%s】%s", p->ip, p->name, buf);
for(auto it=clients.begin(); it != clients.end(); it++) {
if (it->socket != p->socket) {
write(it->socket, buff2, strlen(buff2)+1);
}
}
}
clients.remove(*p);
delete p;
return NULL;
}
int main()
{
int sock = socket(AF_INET,SOCK_STREAM,0);
struct sockaddr_in server_socket;
struct sockaddr_in client_socket;
bzero(&server_socket,sizeof(server_socket));
server_socket.sin_family = AF_INET;
server_socket.sin_port = htons(_PORT_);
server_socket.sin_addr.s_addr = htonl(INADDR_ANY);
bind(sock,(struct sockaddr *)&server_socket,sizeof(struct sockaddr_in));
listen(sock,_BACKLOG_);
while(1) {
socklen_t len = sizeof(client_socket);
printf("wait accept...\n");
int client_sock = accept(sock,(struct sockaddr *)&client_socket,&len);
if(client_sock < 0) {
printf("accept error, error is %d,errstring is %s\n",errno,strerror(errno));
close(sock);
return 3;
}
client *c = new client;
strcpy(c->ip, inet_ntoa(client_socket.sin_addr));
printf("get connect,ip is %s\n", c->ip);
c->socket = client_sock;
pthread_t tid;
pthread_create(&tid, NULL, client_func, (void*)c);
}
close(sock);
return 0;
}