C实现socket 服务端和客户端
- 一. 服务端和客户端服务流程图
- 二. 服务端的实现
-
- 1.1 服务端和客户端公用文件tcpSocket.h, tcpSocket.cpp
- 1.2 服务端主程序 server.cpp
- 三 客户端的实现
-
一. 服务端和客户端服务流程图
二. 服务端的实现
1.1 服务端和客户端公用文件tcpSocket.h, tcpSocket.cpp
#ifndef _TCPSOCKET_H_
#define _TCPSOCKET_H
#include
#include
#pragma comment(lib, "ws2_32.lib")
#include
#include
#define PORT 8899
#define err(errMsg) printf("[line:%d] %s failed code %d\n", __LINE__, errMsg, WSAGetLastError());
bool init_Socket();
bool close_Socket();
bool sendMsg(int fd, const char* msg);
bool recvMsg(int fd, char* buf, int bufSize);
#endif
#include "tcpSocket.h"
bool init_Socket()
{
WSADATA wsadata;
if (0 != WSAStartup(MAKEWORD(2, 2), &wsadata)) {
err("WSAStartup");
return false;
}
return true;
}
bool close_Socket()
{
if (0 != WSACleanup()) {
err("WSACleanup");
return false;
}
return true;
}
bool sendMsg(int fd, const char* msg) {
int ret = send(fd, msg, strlen(msg) + 1, 0);
if (ret == -1) {
err("send msg");
return false;
}
return true;
}
bool recvMsg(int fd, char* buf, int bufSize) {
int len = recv(fd, buf, bufSize, 0);
if (len > 0) {
printf("服务端说: %s\n", buf);
return true;
}
else if (len == 0)
{
printf("服务器端已经断开了...\n");
}
else {
perror("recv");
}
return false;
}
1.2 服务端主程序 server.cpp
#include "../tcpSocket/tcpSocket.h"
#include
struct SockInfo {
sockaddr_in addr;
int fd;
};
void* working(SockInfo *pinfo);
SockInfo infos[512] = { 0 };
int main() {
init_Socket();
SOCKET fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (fd == -1)
{
err("socket");
return -1;
}
sockaddr_in saddr;
saddr.sin_family = AF_INET;
saddr.sin_port = htons(PORT);
saddr.sin_addr.S_un.S_addr = INADDR_ANY;
int ret = bind(fd, (sockaddr*)&saddr, sizeof(saddr));
if (ret == -1) {
err("bind");
return -1;
}
ret = listen(fd, 10);
if (ret == -1)
{
err("listen");
return -1;
}
printf("等待客户端连接...\n");
int max = sizeof(infos) / sizeof(infos[0]);
for (int i = 0; i < max; ++i)
{
infos[i].fd = -1;
}
int addrLen = sizeof(sockaddr_in);
while (1) {
SockInfo* pinfo = nullptr;
for (int i = 0; i < max; ++i)
{
if (infos[i].fd == -1) {
pinfo = &infos[i];
break;
}
}
int cfd = accept(fd, (struct sockaddr*)&pinfo->addr, &addrLen);
if (cfd == -1) {
err("accept");
break;
}
pinfo->fd = cfd;
std::thread Worker(working, pinfo);
Worker.detach();
}
closesocket(fd);
close_Socket();
return 0;
}
void* working(SockInfo *pinfo)
{
char ip[32];
printf("客户端fd: %d, IP:%s, 端口:%d\n",
pinfo->fd,
inet_ntop(AF_INET, &pinfo->addr.sin_addr.S_un, ip, sizeof(ip)),
ntohs(pinfo->addr.sin_port)
);
while (1) {
char buf[1024];
if (recvMsg(pinfo->fd, buf, sizeof(buf))) {
sendMsg(pinfo->fd, buf);
}
}
int ret = closesocket(pinfo->fd);
if (ret == 0)
{
printf("释放客户端fd:%d\n", pinfo->fd);
}
pinfo->fd = -1;
return NULL;
}
三 客户端的实现
3.1 客户端主程序 client.cpp
#include
#include "../tcpSocket/tcpSocket.h"
int main()
{
init_Socket();
SOCKET fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (fd == -1)
{
err("socket");
return -1;
}
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(PORT);
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.S_un.S_addr);
int ret = connect(fd, (sockaddr*)&addr, sizeof(addr));
if ( ret == -1)
{
err("connect");
return -1;
}
int number = 0;
while (1) {
sendMsg(fd, "你好,我是客户端");
char recvBuf[BUFSIZ];
memset(recvBuf, 0, sizeof(recvBuf));
if (!recvMsg(fd, recvBuf, sizeof(recvBuf))){
break;
}
printf("接收到的消息:%s\n", recvBuf);
Sleep(1000);
}
closesocket(fd);
close_Socket();
return 0;
}