客户端任务:
- 能从键盘获取输入,发给服务器
- 能收到服务器的消息,并打印
服务器任务:
- 接收客户端的消息,把消息原封不动的返回去
客户端伪代码:子进程read,父进程write
客户端代码:
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h> /* superset of previous */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
using namespace std;
#include <errno.h>
#define PUB_MSG_TYPE 256
#define ERR_EXIT(m) \
do{\
perror(m);\
_exit(1); \
} while (0)
int main()
{
int ret = 0;
int socket_fd = socket(AF_INET, SOCK_STREAM, 0);//创建socket
if (socket_fd == 1)
ERR_EXIT("socket");
//绑定ip和端口
struct sockaddr_in ser_addr;
ser_addr.sin_family = AF_INET;
ser_addr.sin_port = htons(8095);
inet_aton("192.168.1.9", &ser_addr.sin_addr);
ret = connect(socket_fd, (struct sockaddr*)&ser_addr, sizeof(ser_addr));
if (ret == -1)
ERR_EXIT("connect");
cout << "connect success" << endl;
pid_t pid = fork();
if (pid == 0)
{
//子进程进行读取数据
char rbuf[1024] = { 0 };
while (1)
{
ret = read(socket_fd, rbuf, sizeof(rbuf));
if (ret == 0)
{
cout << "server is off" << endl;
break;
}
cout << "read:" << rbuf << endl;
memset(rbuf, 0x0, sizeof(rbuf));
}
exit(EXIT_SUCCESS);
}
//父进程负责从键盘获取数据输入 发送给服务器
char sbuf[1024] = { 0 };
while (fgets(sbuf, sizeof(sbuf), stdin) != 0)//stdin标准输入
{
write(socket_fd, sbuf, sizeof(sbuf));
memset(sbuf, 0x0, sizeof(sbuf));
}
return 0;
}
服务器代码
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h> /* superset of previous */
#include <unistd.h>
#include <string.h>
using namespace std;
#include <errno.h>
#define PUB_MSG_TYPE 256
#define ERR_EXIT(m) \
do{\
perror(m);\
exit(1); \
} while (0)
//服务器
int main()
{
int socket_fd = socket(AF_INET, SOCK_STREAM, 0);//创建一个TCPsocket
if (socket_fd == 1)
ERR_EXIT("socket");
//绑定ip和端口
struct sockaddr_in ser_add;
ser_add.sin_family = AF_INET;
ser_add.sin_port = htons(8095);//端口号
ser_add.sin_addr.s_addr = htonl(INADDR_ANY);
//地址可重复使用
int on = 1;
setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
int ret = bind(socket_fd, (struct sockaddr*)&ser_add, sizeof(ser_add));
if (ret == -1)
ERR_EXIT("bind");
ret = listen(socket_fd, SOMAXCONN);//监听数据存放队列中
if (ret == -1)
ERR_EXIT("listen");
struct sockaddr_in cli_add;
socklen_t add_len = sizeof(cli_add);
//int add_len = sizeof(cli_add);
cout << "wait for client..." << endl;
int con_fd = accept(socket_fd, (struct sockaddr*)&cli_add, &add_len);
cout << "someone on line..." << endl;
char buf[1024] = { 0 };
while (1)
{
read(con_fd, buf, sizeof(buf));
cout << "buf=" << buf << endl;
write(con_fd, buf, sizeof(buf));
memset(buf, 0, sizeof(buf));
}
return 0;
}
客户端效果:
服务器效果
以上是只能连接单个服务器
对服务器进行升级可以进行多个服务器的连接
服务器代码:
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h> /* superset of previous */
#include <unistd.h>
#include <string.h>
using namespace std;
#include <errno.h>
#define PUB_MSG_TYPE 256
#define ERR_EXIT(m) \
do{\
perror(m);\
exit(1); \
} while (0)
//服务器
int main()
{
int socket_fd = socket(AF_INET, SOCK_STREAM, 0);//创建一个TCPsocket
if (socket_fd == 1)
ERR_EXIT("socket");
//绑定ip和端口
struct sockaddr_in ser_add;
ser_add.sin_family = AF_INET;
ser_add.sin_port = htons(8095);//端口号
ser_add.sin_addr.s_addr = htonl(INADDR_ANY);
//地址可重复使用
int on = 1;
setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
int ret = bind(socket_fd, (struct sockaddr*)&ser_add, sizeof(ser_add));
if (ret == -1)
ERR_EXIT("bind");
ret = listen(socket_fd, SOMAXCONN);//监听数据存放队列中
if (ret == -1)
ERR_EXIT("listen");
struct sockaddr_in cli_add;
socklen_t add_len = sizeof(cli_add);
//int add_len = sizeof(cli_add);
cout << "wait for client..." << endl;
while (1)
{
int con_fd = accept(socket_fd, (struct sockaddr*)&cli_add, &add_len);
cout << "someone on line..." << endl;
pid_t pid = fork();
if (pid == 0)
{
char buf[1024] = { 0 };
while (1)
{
ret = read(con_fd, buf, sizeof(buf));
if (ret == 0)
{
cout << "client is offline" << endl;
break;
}
cout << "buf=" << buf << endl;
write(con_fd, buf, sizeof(buf));
memset(buf, 0, sizeof(buf));
}
exit(EXIT_SUCCESS);
}
}
return 0;
}
效果图
服务器可以接收多个客户端
客户端1
客户端2