1、客户端
/*
* File: TCPEchoClient4.c
* Author: 云守护 客户端
*
* Created on 2013年11月13日, 下午3:49
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include "DieWithMessage.h"
int main(int argc, char** argv) {
if(argc<3||argc>4)
{
DieWithUserMessage("param","<server Address><Echo Word>[<Server Port>]");
}
char* server_IP=argv[1];
char* echoString=argv[2];
in_port_t server_port=(argc==4)?atoi(argv[3]):7;
int sock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(sock<0)
{
DieWithSystemMessage("socket failed!");
}
//配置服务端socket信息
struct sockaddr_in server_addr;
memset(&server_addr,0,sizeof(server_addr));
server_addr.sin_family=AF_INET;
//转换地址,转换成网络地址
int rtnVal=inet_pton(AF_INET,server_IP,&server_addr.sin_addr.s_addr);
if(rtnVal==0)
DieWithUserMessage("inet_pton failed!","invalid address string");
else if(rtnVal<0)
{
DieWithSystemMessage("inet_pton failed!");
}
server_addr.sin_port=htons(server_port);
if(connect(sock,(struct sockaddr*)&server_addr,sizeof(server_addr))<0)
{
DieWithSystemMessage("connect() failed!");
}
size_t echoStringLen=strlen(echoString);
//发送数据,阻塞模式
ssize_t numBytes=send(sock,echoString,echoStringLen,0);
if(numBytes<0)
DieWithSystemMessage("send() failed");
else if(numBytes!=echoStringLen)
DieWithUserMessage("send() ","sent unexpected number of bytes");
unsigned int totalBytesRcvd=0;
fputs("Received: ",stdout);
while(totalBytesRcvd<echoStringLen)
{
char buffer[BUFSIZ];
//接收数据
numBytes=recv(sock,buffer,BUFSIZ-1,0);
if(numBytes<0)
DieWithSystemMessage("recv(0 failed!");
else if(numBytes==0)
{
DieWithUserMessage("recv()","connection closed prematurely");
}
totalBytesRcvd+=numBytes;
buffer[numBytes]='\0';
fputs(buffer,stdout);
}
fputc('\n',stdout);
close(sock);
return (EXIT_SUCCESS);
}
/*
* File: DieWithMessage.h
* Author: root
*
* Created on 2013年11月13日, 下午3:52
*/
#ifndef DIEWITHMESSAGE_H
#define DIEWITHMESSAGE_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdio.h>
#include <stdlib.h>
void DieWithUserMessage(const char *msg,const char * detail)
{
fputs(msg,stderr);
fputs(":",stderr);
fputs(detail,stderr);
fputs("\n",stderr);
exit(1);
}
void DieWithSystemMessage(const char* msg)
{
perror(msg);
exit(1);
}
#ifdef __cplusplus
}
#endif
#endif /* DIEWITHMESSAGE_H */
2、服务端
/*
* File: TCPEchoServer4.c 服务端
* Author: 云守护
*
* Created on 2013年11月14日, 上午10:10
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include "DieWithMessage.h"
static const int MAXPENDING=10;
void HandleTCPClient(int client_sock)
{
char buffer[BUFSIZ];
//先接收客户端的数据
ssize_t numBytesRcvd =recv(client_sock,buffer,BUFSIZ,0);
if(numBytesRcvd<0)
DieWithSystemMessage("recv() failed!");
while(numBytesRcvd>0)
{
//发送数据回去
ssize_t numBytesSent=send(client_sock,buffer,numBytesRcvd,0);
if(numBytesSent<0)
DieWithSystemMessage("send() failed!");
else if(numBytesSent!=numBytesRcvd)
{
DieWithUserMessage("send()","sent unexpected number of bytes");
}
//继续接收数据
numBytesRcvd=recv(client_sock,buffer,BUFSIZ,0);
if(numBytesRcvd<0)
DieWithSystemMessage("recv() failed!");
}
close(client_sock);
}
int main(int argc, char** argv) {
if(argc!=2)
{
DieWithUserMessage("param","<Server Port>");
}
in_port_t server_port=atoi(argv[1]);
//建立
int server_sock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(server_sock<0)
{
DieWithSystemMessage("socket() failed");
}
//配置服务器socket
struct sockaddr_in server_addr;
memset(&server_addr,0,sizeof(server_addr));
server_addr.sin_family=AF_INET;
server_addr.sin_addr.s_addr=htonl(INADDR_ANY);
server_addr.sin_port=htons(server_port);
//绑定端口
if(bind(server_sock,(struct sockaddr*)&server_addr,sizeof(server_addr))<0)
{
DieWithSystemMessage("bind() failed!");
}
//监听端口
if(listen(server_sock,MAXPENDING)<0)
{
DieWithSystemMessage("listen(0 failed!");
}
printf("server start success on %d \n",server_port);
for(;;)
{
//启动成功,等待客户端链接,
//client_addr保存客户端地址信息
struct sockaddr_in client_addr;
socklen_t client_addr_len=sizeof(client_addr);
//获取客户端socket
int client_sock=accept(server_sock,(struct sockaddr*)&client_addr,&client_addr_len);
if(client_sock<0)
{
DieWithSystemMessage("accept() failed!");
}
//获取客户端IP和端口
char clientName[INET_ADDRSTRLEN];
if(inet_ntop(AF_INET,&client_addr.sin_addr.s_addr,clientName,sizeof(clientName))!=NULL)
{
printf("Handing Client %s /%d \n",clientName,ntohs(client_addr.sin_port));
}else{
puts("Unable to get client address!");
}
//处理数据
HandleTCPClient(client_sock);
}
return (EXIT_SUCCESS);
}