1. socket 服务器与客户端开发步骤
2. TCP 服务器与客户端编程
2.1 代码示例 server.c
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char **argv)
{
int s_fd;
int c_fd;
int n_read;
int iRet;
char readBuf[128];
int mark = 0;
char msg[128] = {0};
struct sockaddr_in s_addr;
struct sockaddr_in c_addr;
if (argc != 3)
{
printf("param is not good\n");
exit(-1);
}
memset(&s_addr, 0, sizeof(struct sockaddr_in));
memset(&c_addr, 0, sizeof(struct sockaddr_in));
// 1. socket
s_fd = socket(AF_INET, SOCK_STREAM, 0);
if (s_fd == -1)
{
perror("socket");
exit(-1);
}
// 2. bind 配置 struct sockaddr_in 结构体,绑定时再转换成 struct sockaddr * 结构体类型
s_addr.sin_family = AF_INET;
s_addr.sin_port = htons(atoi(argv[2]));
inet_aton(argv[1], &s_addr.sin_addr);
iRet = bind(s_fd, (struct sockaddr *)&s_addr, sizeof(struct sockaddr_in));
if (iRet == -1)
{
perror("bind");
exit(-1);
}
// 3. listen
iRet = listen(s_fd, 10);
if (iRet == -1)
{
perror("listen");
exit(-1);
}
// 4. accept
int clen = sizeof(struct sockaddr_in);
while (1)
{
c_fd = accept(s_fd, (struct sockaddr *)&c_addr, &clen);
if (c_fd == -1)
{
perror("accept");
exit(-1);
}
mark++;
printf("get connect: %s\n", inet_ntoa(c_addr.sin_addr));
// 接收到 connect 后用子进程处理
if (fork() == 0)
{
sprintf(msg, "welcom No.%d client", mark); // 字符串拼接
write(c_fd, msg, strlen(msg));
// 不断的读取客户端发送到 c_fd 的内容
while (1)
{
memset(readBuf, 0, sizeof(readBuf));
n_read = read(c_fd, readBuf, 128);
if (n_read == -1)
{
perror("read");
}
else if (n_read > 0)
{
printf("\nget command: %s \n", readBuf);
}
else
{
printf("client quit\n");
break;
}
}
}
}
return 0;
}
2.2 代码示例 client.c
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char **argv)
{
int c_fd;
int n_read;
char readBuf[128];
int tmp;
char msg[128] = {0};
struct sockaddr_in c_addr;
memset(&c_addr, 0, sizeof(struct sockaddr_in));
if (argc != 3)
{
printf("param is not good\n");
exit(-1);
}
// 1. socket 配置 struct sockaddr_in 结构体,连接时再转换成 struct sockaddr * 结构体类型
c_fd = socket(AF_INET, SOCK_STREAM, 0);
if (c_fd == -1)
{
perror("socket");
exit(-1);
}
// 2.connect
c_addr.sin_family = AF_INET;
c_addr.sin_port = htons(atoi(argv[2]));
inet_aton(argv[1], &c_addr.sin_addr);
if (connect(c_fd, (struct sockaddr *)&c_addr, sizeof(struct sockaddr)) == -1)
{
perror("connect");
exit(-1);
}
// 连接成功
memset(readBuf, 0, sizeof(readBuf));
n_read = read(c_fd, readBuf, 128);
if (n_read == -1)
{
perror("read");
}
else
{
printf("\nget:%s\n", readBuf);
}
// 不断的接收终端的命令发送至 c_fd
while (1)
{
memset(msg, 0, sizeof(msg));
printf("input: ");
gets(msg);
write(c_fd, msg, strlen(msg));
}
return 0;
}
2.3 程序运行结果
实现服务器连接多客户端并通信。