socket编程---服务器端与客户端简单通信

本文介绍了一个简单的TCP服务器及客户端的实现过程,包括Socket创建、绑定、监听、接受连接等核心步骤,并演示了基本的数据收发流程。

服务器端:

/* * File: main.cpp * Author: xiaomo * * Created on 2011年6月22日, 下午8:07 */ #include<stdio.h> #include <stdlib.h> #include <errno.h> #include <string.h> #include <netdb.h> #include <sys/types.h> #include <netinet/in.h> #include <sys/socket.h> #include<unistd.h> #include<arpa/inet.h> #include <time.h> #define SERVER_PORT 2222 // define the defualt connect port id #define LENGTH_OF_LISTEN_QUEUE 10 //length of listen queue in server #define BUFFER_SIZE 10485760 #define WELCOME_MESSAGE "welcome to connect the server. " ssize_t Read(int sockfd, char* recv, size_t bytes) { size_t nleft; ssize_t nread; char *ptr = recv; nleft = bytes; while(nleft > 0) { if((nread = read(sockfd, ptr, nleft)) < 0) { if(errno == EINTR) nread = 0; else return -1; } else if(nread == 0) break; nleft -= nread; ptr += nread; } return(bytes - nleft); } ssize_t Write(int sockfd, char* send, size_t bytes) { size_t nleft; ssize_t nwritten; char* ptr = send; nleft = bytes; while(nleft > 0) { if((nwritten = write(sockfd, ptr, nleft)) <= 0) { if(nwritten < 0 && errno == EINTR) nwritten = 0; else return -1; } nleft -= nwritten; ptr += nwritten; } return bytes; } int main(int argc, char **argv) { int servfd,clifd; struct sockaddr_in servaddr,cliaddr; int recvbytes; if ((servfd = socket(AF_INET,SOCK_STREAM,0)) < 0) {//建立Socket,程序调用Socket函数,该函数返回一个类似于文件描述符的句柄 printf("create socket error!n"); exit(1); } //sin_zero用来将sockaddr_in结构填充到与struct sockaddr同样的长度,可以用bzero()或memset()函数将其置为零 bzero(&servaddr,sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(SERVER_PORT); servaddr.sin_addr.s_addr = htons(INADDR_ANY);/*系统自动填入本机IP地址 */ if (bind(servfd,(struct sockaddr*)&servaddr,sizeof(servaddr))<0) {//服务端通过调用 bind函数来配置本地信息。Bind函数将socket与本机上的一个端口相关联,随后你就可以在该端口监听服务请求。 printf("bind to port %d failure!n",SERVER_PORT); exit(1); } if (listen(servfd,LENGTH_OF_LISTEN_QUEUE) < 0) {//Listen函数使socket处于被动的监听模式,并为该socket建立一个输入数据队列,将到达的服务请求保存在此队列中,直到程序处理它们。 printf("call listen failure!n"); exit(1); } while (1) {//server loop will nerver exit unless any body kill the proces long timestamp; socklen_t length = sizeof(cliaddr); //accept()函数让服务器接收客户的连接请求 clifd = accept(servfd,(struct sockaddr*)&cliaddr,&length); if (clifd < 0) { printf("error comes when call accept!n"); break; } char* buf = new char[BUFFER_SIZE]; strcpy(buf,WELCOME_MESSAGE); //inet_ntop(INET_ADDRSTRLEN,cliaddr.sin_addr,buf,BUFFER_SIZE); printf("from client,IP:%s,Port:%dn",inet_ntoa(cliaddr.sin_addr),ntohs(cliaddr.sin_port)); timestamp = time(NULL); strcat(buf,"/ntimestamp in server:"); strcat(buf,ctime(×tamp)); //Send()函数返回实际上发送出的字节数,可能会少于你希望发送的数据 Write(clifd,buf,BUFFER_SIZE); if ((recvbytes=Read(clifd, buf, BUFFER_SIZE)) ==-1) { perror("recv出错!"); exit(1); } buf[recvbytes]='/0'; printf("/nReceived from Client: %s",buf); delete []buf; close(clifd); }//exit close(servfd); return 0; }

客户端:

/* * File: main.cpp * Author: xiaomo * * Created on 2011年6月18日, 下午6:38 */ #include<stdio.h> #include <stdlib.h> #include <errno.h> #include <string.h> #include <netdb.h> #include <sys/types.h> #include <netinet/in.h> #include <sys/socket.h> #include<unistd.h> #include<arpa/inet.h> #define SERVPORT 2222 #define MAXDATASIZE 1024 /*每次最大数据传输量 */ #define BUFFER_SIZE 255 #define FROMCLIENT "Hi,I'm client./n" int main(int argc, char *argv[]){ int sockfd, recvbytes; char buf[MAXDATASIZE]; // char server_ip[64]; struct sockaddr_in serv_addr; // fgets(server_ip,BUFSIZ,stdin); //从键盘输入数据 if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){ perror("error!"); exit(1); } serv_addr.sin_family=AF_INET; serv_addr.sin_port=htons(SERVPORT); serv_addr.sin_addr.s_addr = htons(INADDR_ANY);//inet_addr(server_ip) bzero(&(serv_addr.sin_zero),8); if (connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr)) == -1) { perror("connect出错!"); exit(1); } if ((recvbytes=recv(sockfd, buf, MAXDATASIZE, 0)) ==-1) { perror("recv出错!"); exit(1); } buf[recvbytes] = '/0'; printf("/nReceived from Server: %s",buf); strcpy(buf,FROMCLIENT); send(sockfd,buf,BUFFER_SIZE,0); close(sockfd); return 0; }

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值