欢迎光临
我们一直在努力

寒假学习(9)(C语言9+模数电9)

写了一个聊天室,可以支持多人在线,但是现在的问题是发送信息存在无法覆盖的问题

第一个是服务端的代码,第二个是客户端的代码

//聊天室
//服务端流程
//1 创建socket套接字:网络接口

//2 绑定IP和端口号;IP是电脑的地址,端口号是APP的地址

//3 监听:只是用来接收连接的

//4 接收客户端连接

//5 接收客户端消息

//6 发送消息给客户端

//7 关闭套接字

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <WinSock2.h>
#pragma comment(lib, "ws2_32.lib")

//客户端线程函数
DWORD WINAPI client_thread(LPVOID lpParameter);

int main ()
{
//在windos上开启网络权限
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
//非常固定,只有windos需要

//创建套接字
/*
SOCKET socket(int af, int type, int protocol);
af: 地址族,AF_INET表示IPv4 // AF_INET6表示IPv6
type: 套接字类型,SOCK_STREAM表示TCP//一个是流式协议,一个是数据包
protocol: 协议,0表示使用默认协议
*/

SOCKET listen_socket = socket(AF_INET, SOCK_STREAM, 0);

//判读是否创建成功
if (listen_socket == INVALID_SOCKET)
{
printf("socket failed: %d,no creat\\n", WSAGetLastError());
return 1;
}

//绑定IP和端口号

struct sockaddr_in server_addr;

server_addr.sin_family = AF_INET;

server_addr.sin_port = htons(8080);
//这里涉及到大小端问题,htons(8080)表示将8080转换为网络字节序

//server_addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);//可以理解为一个选项 网卡 127.0.0.1(本地回环) 只接受那个网卡的数据
long ip = inet_addr("0.0.0.0");
server_addr.sin_addr.S_un.S_addr = ip;

//sockaddr_in的成员是
//unsigned short sin_family;
//unsigned short sin_port;
//struct in_addr sin_addr;
//sin_family: 地址族,AF_INET表示IPv4
//sin_port: 端口号,htons(8080)表示将8080转换为网络字节序
//sin_addr.S_un.S_addr: IP地址,INADDR_ANY表示任何IP地址

/*

int bind(SOCKET s, const struct sockaddr *addr, int addrlen);

s: 套接字

addr: 地址结构体

addrlen: 地址结构体长度

*/

//sockaddr也是一个结构体,但是它是通用的,可以用于任何协议实际上和sockaddr_in是一样的

int ret = bind(listen_socket, (struct sockaddr *)&server_addr, sizeof(server_addr));

//判断是否绑定成功

if (ret == SOCKET_ERROR)

{

printf("bind failed: %d,no bind\\n", WSAGetLastError());

return 1;

}

//3.开启监听属性

//需要用到listen函数
//listen函数的参数是
//套接字和最大连接数
//最大连接数是指服务器可以同时处理的最大连接数
//如果服务器的连接数超过了最大连接数,那么新的连接将被拒绝

//判断是否开启成功
if (listen(listen_socket, 10) == SOCKET_ERROR)
{
printf("listen failed: %d\\n", WSAGetLastError());
closesocket(listen_socket);
WSACleanup();
return 1;
}

//等待客户端连接
//accept函数用于接受客户端连接
//accept函数的参数是
//套接字
//客户端地址结构体
//地址结构体长度
//这是一个阻塞函数,等到客户端连接后才返回,如果没有客户端连接,则一直等待
SOCKET client_socket;
struct sockaddr_in client_addr;
int client_addr_len = sizeof(client_addr);

while(1)
{
client_socket = accept(listen_socket, (struct sockaddr *)&client_addr, &client_addr_len);
//返回的SOCKET是客户端的套接字,才是和客户端通信的套接字

//判断是否连接成功
if (client_socket == INVALID_SOCKET)
{
printf("accept failed: %d\\n", WSAGetLastError());
continue;
}

SOCKET *sockfd = (SOCKET *)malloc(sizeof(SOCKET));
*sockfd = client_socket;

//创建线程处理客户端连接
HANDLE hThread = CreateThread(NULL, 0, client_thread, sockfd, 0, NULL);
if (hThread == NULL)
{
printf("CreateThread failed\\n");
free(sockfd);
closesocket(client_socket);
}
else
{
CloseHandle(hThread);
}

printf("Client connected!\\n");
}

closesocket(listen_socket);
WSACleanup();

return 0;
}

DWORD WINAPI client_thread(LPVOID lpParameter)
{
SOCKET *sockfd = (SOCKET *)lpParameter;
SOCKET client_socket = *sockfd;
free(sockfd);

char buf[1024] = {0};

while(1)
{
int recv_ret = recv(client_socket, buf, sizeof(buf), 0);

if (recv_ret == SOCKET_ERROR)
{
printf("recv failed: %d\\n", WSAGetLastError());
break;
}
else if (recv_ret == 0)
{
printf("Client disconnected\\n");
break;
}

printf("recv: %s\\n", buf);

send(client_socket, buf, recv_ret, 0);
}

closesocket(client_socket);

return 0;
}

//聊天室的客户端
//创建socket套接字
//连接服务器
//发送消息
//接收消息
//关闭套接字(连接)
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")

int main()
{
// 初始化Winsock
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
printf("Failed to initialize Winsock\\n");
return 1;
}

// 创建套接字

SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);

if (sock == INVALID_SOCKET) {

printf("Failed to create socket\\n");

WSACleanup();

return 1;

}

//连接服务器
struct sockaddr_in target;
target.sin_family = AF_INET;
target.sin_port = htons(8080);
target.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");

if (connect(sock, (struct sockaddr*)&target, sizeof(target)) == SOCKET_ERROR) {
printf("Failed to connect to server\\n");
closesocket(sock);
WSACleanup();
return 1;
}

while(1)
{
//发送信息
char buffer[1024];
printf("请输入要发送的信息:");
scanf("%s", buffer);
send(sock, buffer, strlen(buffer), 0);

// 接收服务器响应
memset(buffer, 0, sizeof(buffer));
int ret = recv(sock, buffer, sizeof(buffer) – 1, 0);
printf("收到服务器响应:%s\\n", buffer);
if(ret<=0)break;
}

// 关闭套接字和清理Winsock
closesocket(sock);
WSACleanup();

return 0;
}

赞(0)
未经允许不得转载:171主机测评 » 寒假学习(9)(C语言9+模数电9)
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址