您的位置:首页 > 理论基础 > 计算机网络

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

2013-10-25 21:45 513 查看
/***************************************************************************************************************************************************************************

*文件: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);

}

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

结果:


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


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

注意点:

编译过程中,小结:

(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)监听端口的问题:

服务端怎么知道和客户端的哪个进程连接???

服务器在客户端连接后,会在监听套接字之外另外生成一个新的套接字,表示与客户端的连接,这个套接字了解客户端的地址和端口号,从而可以区分是哪个客户端;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: