TCP/IP,单进程服务器与客户端连接通信,ipv4,TCP传输,无复用简单实例
一、实例设定
1、服务器与客户端均是本机,服务器绑定的ip可以是宏INADDR_ANY,这个宏表示可以和本机的所有网卡绑定,客户端连接的ip是127.0.0.1,这个ip就代表本机。
2、服务端可以将客户端发送的字符串使用toupper函数小写转大写,然后打印在屏幕上。
3、服务器为单进程,单次连接,仅一次连接非复用案例。
4、此实例用于梳理连接的思路
5、这里使用的Bind,Accept等函数是在头文件中引用了的,使用的时候使用库函数就行,详细的看这篇
网络编程中的任何函数在调用时都需要检查返回值的简化做法
二、服务器的连接步骤
1、建立监听套接字用于接收客户端
int lfd = 0;
lfd = Socket(AF_INET, SOCK_STREAM, 0);
2、监听套接字绑定ip和端口
#define SERV_PORT 9527
struct sockaddr_in serv_addr;
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(SERV_PORT);
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
3、设置监听上限
Listen(lfd,128);
4、阻塞,接收来自客户端的连接
int cfd = 0
struct sockaddr_in clit_addr;
clit_addr_len = sizeof(clit_addr);
cfd = Accept(lfd, (struct sock_addr*)&clit_addr,&clit_addr_len);
5、阻塞,从客户端套接字中读取信息并打印
int ret = 0;
ret = read(cfd,buf,sizeof(buf));
write(STDOUT_FILENO, buf, ret);
6、对接收到的数据进行处理并发回
for(i = 0;i<ret;i++)
buf[i] = toupper(buf[i]);
write(cfd, buf, ret);
7、关闭双套接字
close(lfd);
close(cfd);
三、服务器整体代码
#include "tcp_socket.h"
#define SERV_PORT 9527
int main(int argc, char *argv[])
{
int lfd = 0,cfd = 0;
struct sockaddr_in serv_addr,clit_addr;
socklen_t clit_addr_len, client_IP_len;
int ret,i;
char buf[BUFSIZ], client_IP[1024];
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(SERV_PORT);
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
lfd = Socket(AF_INET, SOCK_STREAM, 0);
Bind(lfd,(struct sock_addr*)&serv_addr,sizeof(serv_addr));
Listen(lfd,128);
clit_addr_len = sizeof(clit_addr);
cfd = Accept(lfd, (struct sock_addr*)&clit_addr,&clit_addr_len);
printf("client IP: %s, port: %d\n",
inet_ntop(AF_INET, &clit_addr.sin_addr.s_addr, client_IP, sizeof(client_IP)),
ntohs(clit_addr.sin_port));
while(1)
{
ret = read(cfd,buf,sizeof(buf));
write(STDOUT_FILENO, buf, ret);
if(ret == 1)
{
printf("input 0,return\n");
close(cfd);
}
for(i = 0;i<ret;i++)
buf[i] = toupper(buf[i]);
write(cfd, buf, ret);
}
close(lfd);
close(cfd);
return 0;
}
四、使用nc模拟客户端进行连接,单次连接,单进程服务器,实例完成,流程走通。