linux网络编程(一对一)

下面的代码实现了非常简单的服务器与客户端的一对一通讯

服务器开启后,可以一直接受客户端发消息,并且在接收到信息后给出回应,直到客户端主动关闭,使服务器等待下一个客户端启动

用到的C语言网络通信:socket创建,bind绑定,accept阻塞,listen监听,read、write读写操作,以及connect连接操作

 

Server:

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>

int main() {
int s_fd, c_fd;
struct sockaddr_in s_addr, c_addr;
socklen_t len;
char readBuf[128];
char *writeBuf = "I get you!";
// 1. 创建socket网络套接字
s_fd = socket(AF_INET, SOCK_STREAM, 0);
if (s_fd == -1) {
perror("socket");
exit(-1);
}

// 2. 绑定本地IP地址和端口号到socket网络套接字上
memset(&s_addr, 0, sizeof(struct sockaddr_in));
s_addr.sin_family = AF_INET;
s_addr.sin_port = htons(8421);
inet_aton("192.168.190.141", &s_addr.sin_addr);
if (bind(s_fd, (struct sockaddr*)&s_addr, sizeof(struct sockaddr_in)) == -1) {
perror("bind");
exit(-1);
}

// 3. 将socket套接字变为监听套接字,准备接受客户端的连接
if (listen(s_fd, 10) == -1) {
perror("listen");
exit(-1);
}

// 4. 服务器阻塞等待客户端的连接
len = sizeof(struct sockaddr_in);
// 服务器主循环
while (1) {
// 4. 服务器阻塞等待客户端的连接
len = sizeof(struct sockaddr_in);
c_fd = accept(s_fd, (struct sockaddr*)&c_addr, &len);
if (c_fd == -1) {
perror("accept");
exit(-1);
}
printf("Success Connected\n");
printf("get connect :%s\n", inet_ntoa(c_addr.sin_addr));

// 循环读取客户端发送的每条消息
while (1) {
memset(readBuf, 0, sizeof(readBuf)); // 清空缓冲区
int n_read = read(c_fd, readBuf, sizeof(readBuf));
if (n_read > 0) {
// 正常接收到消息
printf("get message:%d, %s\n", n_read, readBuf);
} else if (n_read == 0) {
// 客户端关闭连接
printf("Client disconnected.\n");
break; // 跳出循环,等待下一个客户端连接
} else {
// 读取失败
perror("read");
break; // 跳出循环
}
write(c_fd,writeBuf,sizeof(writeBuf));
}

// 关闭客户端套接字
close(c_fd);
}

close(s_fd); // 关闭服务器套接字
return 0;
}
 
Client:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>

int main() {
int c_fd;
struct sockaddr_in s_addr;
char msg[128], readBuf[128];

// 1. 创建socket网络套接字
c_fd = socket(AF_INET, SOCK_STREAM, 0);
if (c_fd == -1) {
perror("socket");
exit(-1);
}

// 2. 连接服务端
memset(&s_addr, 0, sizeof(struct sockaddr_in));
s_addr.sin_family = AF_INET;
inet_aton("192.168.190.141", &s_addr.sin_addr);
s_addr.sin_port = htons(8421);

if (connect(c_fd, (struct sockaddr*)&s_addr, sizeof(struct sockaddr_in)) == -1) {
perror("connect");
exit(-1);
}
printf("Connected to server at %s\n", inet_ntoa(s_addr.sin_addr));

// 3. 发送信息到服务端
while (scanf("%127s", msg) == 1) { // 使用%127s防止缓冲区溢出
if (write(c_fd, msg, strlen(msg)) == -1) {
perror("write");
break;
}

// 4. 读取服务端发来的消息
int n_read = read(c_fd, readBuf, sizeof(readBuf));
if (n_read > 0) {
readBuf[n_read] = '\0'; // 确保字符串以null字符结尾
printf("Received message: %s\n", readBuf);
} else if (n_read == -1) {
perror("read");
break;
} else if (n_read == 0) {
printf("Server closed the connection.\n");
break;
}
}

close(c_fd);
return 0;
}
posted @   小犟  阅读(7)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示