Linux下C/S模型的TCP_socket通信代码

/***************************************************************************************************************************************************************************
 *文件:service.c
 *描述:服务器端程序,接收客户端请求消息,发送确认回执“--OK”
 */


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>


#define PORT 4321
#define MAX_NUM 5 //指定允许等待的最大连接数
#define BUFFERSIZE 1024


int main()
{
int sockfd;
struct sockaddr_in server_addr;//socket地址结构
//创建socket端口,函数原型:int socket(int domain,int type,int protocol);
//指定了IPV4协议,字节流传输
sockfd = socket(AF_INET,SOCK_STREAM,0);
if(sockfd == -1)
{
perror("Creat socket fail:");
exit(1);
}
else
{
printf("Server creat socket success!\n");
}


//创建socket后进行地址绑定,调用bind函数,原型:
//int bind(int sockfd,const struct sockaddr *addr,socklen_t addrlen);
server_addr.sin_family = AF_INET;//使用IPV4协议
server_addr.sin_addr.s_addr = INADDR_ANY;//sockaddr_in机构体中成员sin_addr结构体中s_addr成员表示一个32位的IPV4地址
server_addr.sin_port = htons(PORT);//htons函数将主机字节序转换为网络
bzero(&(server_addr.sin_zero),8);//将结构体中用于对齐的数组填充0

if(bind(sockfd,(struct sockaddr *)&server_addr,sizeof(server_addr)) < 0) {
perror("Bind error:");
exit(1);
}
else
{
printf("Server bind success!\n");
}
//调用listen函数进行监听
//函数原型:int listen(sockfd,int backlog);
if(listen(sockfd,MAX_NUM) < 0)
{
perror("Listen error:");
exit(1);
}
else 
{
printf("Server listen success:\n");
}

while(1)
{
int client_fd;//用于表示链接上的sockfd
struct sockaddr_in client_addr;
socklen_t length = sizeof(client_addr);

//调用accept函数等待客户端链接
if((client_fd=accept(sockfd,(struct sockaddr *)&client_addr,&length)) < 0)
{
perror("Server accept error:");
exit(1);
}
else
{
printf("Server acept success:\n");
printf("Create connection with %s\n", inet_ntoa(client_addr.sin_addr));
}


char recvbuf[BUFFERSIZE] = {0};
char sendbuf[BUFFERSIZE] = {0};
//调用recv和send函数进行接收和发送操作
if(recv(client_fd,recvbuf,BUFFERSIZE,0) == -1)
{
perror("!!!!\n");
printf("Recv error!\n");
break;
}
else
{
//打印接收到的信息,并且返回确认消息
printf("Recvived message :%s\n",recvbuf);
strcpy(sendbuf,recvbuf);
strcat(sendbuf,"--OK");
if(send(client_fd,sendbuf,strlen(sendbuf),0) == -1)
{
printf("Server send error!\n");
break;
}

}
//关闭socket
close(client_fd);
}


exit(0);
}








/******************************************************************************************************************************************************************************

 *文件:client.c
 *描述:向服务器端发送一个消息,并且得到确认
 * 向服务器发送消息,并且收到服务器的确认消息"--OK",打印在终端上
 */


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>
#include <netinet/in.h>




#define PORT 4321
#define BUFFERSIZE 1024


int main(int argc,char *argv[])
{
if(argc != 2)
{
printf("Usage:./%s ServerAddress \n",argv[0]);
exit(1);
}


struct sockaddr_in server_addr;
int connected;
char sendbuf[BUFFERSIZE] = {0};
char recvbuf[BUFFERSIZE] = {0};
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(PORT);
inet_aton(argv[1],&server_addr.sin_addr);//该函数将参数argv[1]转换为32位地址
bzero(&(server_addr.sin_zero),8);
//创建sockfd
if((connected = socket(AF_INET,SOCK_STREAM,0)) < 0)
{
perror("Client creat socket error:");
exit(1);
}


//调用connect函数,主动连接服务器
if(connect(connected,(struct sockaddr *)&server_addr,sizeof(server_addr)) < 0)
{
perror("Connect error:");
exit(1);


}
else
{
printf("Connect success:\n");
printf("Input message: \n");
scanf("%s",sendbuf);
}


//发送和接收消息
if(send(connected,sendbuf,strlen(sendbuf),0) < 0)
{
perror("Send error:");
exit(1);
}
else
{
if(recv(connected,recvbuf,BUFFERSIZE,0) < 0)
{
perror("Recv error:");
exit(1);
}
}

printf("The message from server:%s\n",recvbuf);
close(connected);
exit(0);

}


扫描二维码关注公众号,回复: 10213715 查看本文章




************************************************************************************************************************************************************************

结果:

这是客户端,发送我要吃苹果得到服务器端确认。


这是服务器端,从启动到循环等待客户端。



注意点:

编译过程中,小结:

(1)socket operation on non-socket 的原因:

比如: if   (new_fd   =   accept(sockfd,   (struct   sockaddr   *)&their_addr,&sin_size)   ==   -1)   这样的语句,应该改为

if((new_fd = accept(sockfd,(struct sockaddr *)&their_addr,&sin_size)) ==-1).

(2)监听端口的问题:

 服务端怎么知道和客户端的哪个进程连接???
    服务器在客户端连接后,会在监听套接字之外另外生成一个新的套接字,表示与客户端的连接,这个套接字了解客户端的地址和端口号,从而可以区分是哪个客户端;

发布了61 篇原创文章 · 获赞 6 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/shayueqing/article/details/13042291