使用套接字socket实现服务器和客户端之间的TCP通信。
流程如下:
实现代码:
/* server.c */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <errno.h>
#include <ctype.h>
#define SERV_PORT 9527
void sys_err(const char *str)
{
perror(str);
exit(1);
}
int main(int argc, char *argv[])
{
struct sockaddr_in serv_addr, client_addr;
socklen_t client_addr_len;
char buf[BUFSIZ], client_IP[1024];
//1. 创建监听套接字
int lfd = socket(AF_INET, //IPV4
SOCK_STREAM,
0);
if(lfd == -1) //check RETURN VALUE
{
sys_err("socket error");
}
//2. 绑定本地的IP地址和端口号
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(SERV_PORT);
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
int ret = bind(lfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
if(ret == -1)
{
sys_err("bind error");
}
//3. 设置监听
int ret_listen = listen(lfd, 128);
if(ret_listen == -1)
{
sys_err("listen error");
}
//4. 阻塞等待,连接的到达,连接成功后返回通信用的套接字
client_addr_len = sizeof(client_addr);
int cfd = accept(lfd, (struct sockaddr*)&client_addr, &client_addr_len);
if(cfd == -1)
{
sys_err("accept error");
}
printf("client ip is %s, port is %d\n",
inet_ntop(AF_INET, &client_addr.sin_addr.s_addr, client_IP, sizeof(client_IP)),
ntohs(client_addr.sin_port));
//5. 开始通信
while(1)
{
ssize_t ret_acc = read(cfd, buf, sizeof(buf));
write(STDOUT_FILENO, buf, ret_acc);
for(int i = 0; i < ret_acc; i++)
{
buf[i] = toupper(buf[i]);
}
write(cfd, buf, ret_acc);
}
close(lfd);
close(cfd);
return 0;
}
/* client.c */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <errno.h>
#include <ctype.h>
#define SERV_PORT 9527
void sys_err(const char *str)
{
perror(str);
exit(1);
}
int main(int argc, char *argv[])
{
int cfd;
struct sockaddr_in serv_addr;
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(SERV_PORT);
inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr.s_addr);
char buf[BUFSIZ];
int cnt = 10;
//1. 创建监听套接字
cfd = socket(AF_INET, SOCK_STREAM, 0);
if(cfd == -1)
{
sys_err("socket error");
}
int ret = connect(cfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
if(ret != 0)
{
sys_err("connect error");
}
while(cnt--)
{
write(cfd, "hello\n", 6);
ret = read(cfd, buf, sizeof(buf));
write(STDERR_FILENO, buf, ret);
sleep(1);
}
close(cfd);
return 0;
}
实验现象
客户端向服务器发送10次hello,接收到服务器发来的10次大写HELLO;服务器首先打印IP地址和端口号,随后打印收到的10次由客户端传来的hello。