#include
#include
#include //memset
#include //htos
#include //socket
#include //struct sockaddr
#include //close
#include
void ser() //服务端
{
//第一步建立套接字
int ser_sk = socket(PF_INET, SOCK_STREAM, 0);
//第二步建立地址信息,并用bind进行绑定
struct sockaddr_in ser_add; //建立服务端套接字地址结构
memset(&ser_add, 0, sizeof ser_add);
ser_add.sin_family = AF_INET; //填写对应的port,ip,协议族
ser_add.sin_port = htons(9100);
ser_add.sin_addr.s_addr = htonl(INADDR_ANY); //记得转换为网络字节序
bind(ser_sk, (struct sockaddr*)&ser_add, sizeof ser_add); //绑定IP,port
//第三步监听套接字,创建连接队列
listen(ser_sk, 5);
//第四步进行accpet连接通信
char buffer[1500] = "";
char ip[16] = "";
unsigned short port = 0;
for (int i = 0; i < 2; i++) {
memset(buffer, 0, sizeof buffer);
memset(ip, 0, sizeof ip);
struct sockaddr_in cli_add;
socklen_t cli_len = sizeof cli_add;
int ser_acsk = accept(ser_sk, (struct sockaddr*)&cli_add, &cli_len); //建立连接,获得通信套接字,和对方套接字信息
if (ser_acsk == -1) {
printf("accept failed !\n");
close(ser_sk);
return;
}
//接受信息
inet_ntop(AF_INET, &cli_add.sin_addr.s_addr, ip, 16); //把32为ip地址转化为字符串
port = ntohs(cli_add.sin_port); //网络字节序转化为主机字节序
printf("客户端 : %s %d connnected\n", ip, port);
int len = 0;
while (( len = recv(ser_acsk, buffer, sizeof buffer, 0)) > 0) //接受信息
{
send(ser_acsk, buffer, len , 0 );
memset(buffer, 0, sizeof buffer);
}
close(ser_acsk);
}
printf("ser done!\n");
close(ser_sk);
}
void cli() //客户端
{
//第一步:建立套接字
int cli_sk = socket(PF_INET, SOCK_STREAM, 0); //建立客户端套接字
//第二步建立发送到的地址结构
struct sockaddr_in ser_add;
memset(&ser_add, 0, sizeof ser_add);
ser_add.sin_family = AF_INET;
ser_add.sin_addr.s_addr = inet_addr("127.0.0.1");
ser_add.sin_port = htons(9100);
//第三步骤建立连接,给客户端分配端口
int ret = connect(cli_sk, (struct sockaddr*)&ser_add, sizeof ser_add);
while (ret == 0) {
//第四步发送信息
char buffer[256] = "";
fputs("Input message(Q to quit):", stdout); //输出提示信息
fgets(buffer, sizeof buffer, stdin); //从标准输入流里面读取信息
if ((strcmp(buffer, "q\n") == 0) || (strcmp(buffer, "Q\n") == 0))
{
break;
}
//一个包只能发1K出头的字节数,避免一次发不完
size_t len = strlen(buffer); //发送消息的长度
size_t send_len = 0; //已发送的长度
while (send_len < len) {
ssize_t num = send(cli_sk, buffer + send_len, len - send_len, 0); //发送给服务器
if (num < 0) {
fputs("write failed!\n", stdout);
close(cli_sk);
printf("client done!\n");
return;
}
send_len += num;
}
memset(buffer, 0, sizeof buffer);
size_t read_len = 0; //已读取的长度
while (read_len < len) {
ssize_t num = recv(cli_sk, buffer + read_len, len - read_len, 0); //接受信息
if (num < 0) {
fputs("read failed!\n", stdout);
close(cli_sk);
printf("client done!\n");
return;
}
read_len += num;
}
printf("from server :%s\n", buffer);
}
close(cli_sk);
}
void pra() {
pid_t pid = fork();
if (pid == 0)
{
//开启服务端
ser();
}
else if (pid > 0) {
sleep(1);
for (int i = 0; i < 2; i++) {
cli();
}
int status = 0;
wait(&status);
}
}
int main() {
pra();
return 0;
}
代码运行
#include
#include
#include //memset
#include //htos
#include //socket
#include //struct sockaddr
#include //close
#include
int calulate(int count, int oprand[], char op)
{
int res = 0;
switch (op)
{
case '+':
for (int i = 0; i < count; i++) {
res += oprand[i];
}
break;
case '-':
for (int i = 0; i < count; i++) {
if (i == 0) res = oprand[0];
else res -= oprand[i];
}
break;
case '*':
res = 1;
for (int i = 0; i < count; i++) {
res *= oprand[i];
}
break;
default:
break;
}
return res;
}
void ser() //服务端
{
//第一步建立套接字
int ser_sk = socket(PF_INET, SOCK_STREAM, 0);
//第二步建立地址信息,并用bind进行绑定
struct sockaddr_in ser_add; //建立服务端套接字地址结构
memset(&ser_add, 0, sizeof ser_add);
ser_add.sin_family = AF_INET; //填写对应的port,ip,协议族
ser_add.sin_port = htons(9100);
ser_add.sin_addr.s_addr = htonl(INADDR_ANY); //记得转换为网络字节序
bind(ser_sk, (struct sockaddr*)&ser_add, sizeof ser_add); //绑定IP,port
//第三步监听套接字,创建连接队列
listen(ser_sk, 5);
//第四步进行accpet连接通信
char buffer[1500] = "";
char ip[16] = "";
unsigned short port = 0;
for (int i = 0; i < 2; i++) {
memset(buffer, 0, sizeof buffer);
memset(ip, 0, sizeof ip);
struct sockaddr_in cli_add;
socklen_t cli_len = sizeof cli_add;
int ser_acsk = accept(ser_sk, (struct sockaddr*)&cli_add, &cli_len); //建立连接,获得通信套接字,和对方套接字信息
if (ser_acsk == -1) {
printf("accept failed !\n");
close(ser_sk);
return;
}
//接受信息
inet_ntop(AF_INET, &cli_add.sin_addr.s_addr, ip, 16); //把32为ip地址转化为字符串
port = ntohs(cli_add.sin_port); //网络字节序转化为主机字节序
printf("客户端 : %s %d connnected\n", ip, port);
int len = 0;
while ((len = recv(ser_acsk, buffer, sizeof buffer, 0)) > 0) //接受信息
{
int op_num = (int)buffer[0] & 0xFF;
int ans = calulate(op_num, (int*)(buffer + 1), buffer[op_num * sizeof(int) + 1]);
send(ser_acsk, &ans, sizeof(int), 0);
memset(buffer, 0, sizeof buffer);
}
close(ser_acsk);
}
printf("ser done!\n");
close(ser_sk);
}
void cli() //客户端
{
//第一步:建立套接字
int cli_sk = socket(PF_INET, SOCK_STREAM, 0); //建立客户端套接字
//第二步建立发送到的地址结构
struct sockaddr_in ser_add;
memset(&ser_add, 0, sizeof ser_add);
ser_add.sin_family = AF_INET;
ser_add.sin_addr.s_addr = inet_addr("127.0.0.1");
ser_add.sin_port = htons(9100);
//第三步骤建立连接,给客户端分配端口
int ret = connect(cli_sk, (struct sockaddr*)&ser_add, sizeof ser_add);
while (ret == 0) {
//第四步发送信息
char buffer[256] = "";
fputs("Input message(Q to quit):", stdout); //输出提示信息
std::cin >> buffer;
if ((strcmp(buffer, "q") == 0) || (strcmp(buffer, "Q") == 0))
{
break;
}
memset(buffer, 0, sizeof buffer);
fputs("Operand count:", stdout); //输出提示信息
int op_cnt = 0;
std::cin >> op_cnt;
if (op_cnt <= 1 || op_cnt > 255) {
fputs("Operand count error\n", stdout);
close(cli_sk);
printf("client done!\n");
return;
}
buffer[0] = (char)op_cnt;
for (int i = 0; i < op_cnt; i++) {
std :: cin >> *(int*)(buffer + 1 + i * sizeof(int));
}
fputs("Operator:", stdout);
std :: cin >> buffer[op_cnt * sizeof(int) + 1] ;
printf("\n");
//一个包只能发1K出头的字节数,避免一次发不完
size_t len = strlen(buffer); //发送消息的长度
size_t send_len = 0; //已发送的长度
ssize_t num = send(cli_sk, buffer, op_cnt * sizeof(int) + 2, 0); //发送给服务器
if (num <= 0) {
fputs("send failed!\n", stdout);
close(cli_sk);
printf("client done!\n");
return;
}
printf("send num : %d sleep\n", num);
int ed_ans = -100;
ssize_t re_num = recv(cli_sk, &ed_ans, sizeof(int), 0); //接受信息
if (re_num <= 0) {
fputs("recv failed\n", stdout);
close(cli_sk);
printf("client done!\n");
return;
}
printf("from server :%d\n", ed_ans);
sleep(1);
}
close(cli_sk);
}
void pra() {
pid_t pid = fork();
if (pid == 0)
{
//开启服务端
ser();
}
else if (pid > 0) {
sleep(1);
for (int i = 0; i < 2; i++) {
cli();
}
int status = 0;
wait(&status);
}
}
int main() {
pra();
return 0;
}