TCP三次握手
1.主叫主机发送一个具有同步标志置位的TCP数据包(SYN)给被叫主机--发出连接请求
2.被叫主机收到连接请求后,通过发回具有以下项目的数据包(SYN&ACK)表示接受请求:同步标志置位,数据包的序列号,确认号(其值为已收到的请求包的下一个序列号)
3.主叫主机再回送确认包(ACK)
简单地说:主机向从机发送一个包,从机给主机一次确认,再主机给从机一个确认
服务器端程序:
// File: server.c
#include <stdio.h>                    
#include <strings.h>                    /* for bzero() */
#include <unistd.h>                 /* for close() */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define PORT 1234         //将会被打开的端口
#define BACKLOG 2     //允许的最大连接数
#define MAXDATASIZE 1000    

void process_cli(int connectfd, struct sockaddr_in client);

int main()
{
  int listenfd, connectfd;//socket描述符
  pid_t pid;
  struct sockaddr_in server; //服务器的地址信息
  struct sockaddr_in client; //客户端的地址信息
  int sin_size;

//socket
  if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
  {
        perror("Creating socket failed.");
        exit(1);
  }

  int opt = SO_REUSEADDR;
  setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
//bind
  bzero(&server,sizeof(server));
  server.sin_family=AF_INET;
  server.sin_port=htons(PORT);
  server.sin_addr.s_addr = htonl (INADDR_ANY);
  if (bind(listenfd, (struct sockaddr *)&server, sizeof(struct sockaddr)) == -1)
  {
        perror("Bind error.");
        exit(1);
  }        
//listen
  if(listen(listenfd,BACKLOG) == -1)
  {    
        perror("listen() error\n");
        exit(1);
  }

  sin_size=sizeof(struct sockaddr_in);
  while(1)
  {
//accept
     if ((connectfd = accept(listenfd,(struct sockaddr *)&client,&sin_size))==-1)
     {
                perror("accept() error\n");
                exit(1);
        }
//fork
    if ((pid=fork())>0)
    {
//parent process
         close(connectfd);
         continue;
    }
    else if (pid==0)
    {
//child process
         close(listenfd);
         process_cli(connectfd, client);
         exit(0);        
    }
    else
    {
         printf("fork error\n");
         exit(0);
    }
  }
  close(listenfd);     /* close listenfd */                
}

void process_cli(int connectfd,struct sockaddr_in client)
{
  int num;
  char recvbuf[MAXDATASIZE], sendbuf[MAXDATASIZE], client_name[MAXDATASIZE];

  printf("You got a connection from %s.    ",inet_ntoa(client.sin_addr) );
//recv
  num = recv(connectfd, client_name, MAXDATASIZE,0);
  if (num == 0)
  {
        close(connectfd);
        printf("Client disconnected.\n");
        return;
  }
  client_name[num - 1] = '\0';
  printf("Client's name is %s.\n",client_name);
//recv
  while (num = recv(connectfd, recvbuf, MAXDATASIZE,0))
  {
        recvbuf[num] = '\0';
        printf("Received client( %s ) message: %s",client_name, recvbuf);
        int i;
        for (i = 0; i < num - 1; i++)
        {
             sendbuf[i] = recvbuf[num - i -2];
        }
        sendbuf[num - 1] = '\0';
//send
        send(connectfd,sendbuf,strlen(sendbuf),0);
  }
  close(connectfd);
}
客户端程序:
// File:client.c
#include <stdio.h>
#include <unistd.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>                // for struct hostent    

#define PORT 1234     //将要打开的远程端口
#define MAXDATASIZE 100    

void process(FILE *fp, int sockfd);
char* getMessage(char* sendline,int len, FILE* fp);

int main(int argc, char *argv[])
{
  int socketfd;    
  struct hostent *he;            
  struct sockaddr_in server;    

  if (argc !=2)
  {            
        printf("Usage: %s <IP Address>\n",argv[0]);
        exit(1);
  }
//calls gethostbyname()
  if ((he=gethostbyname(argv[1]))==NULL)
             {    
        printf("gethostbyname() error\n");
        exit(1);
             }
//socket
  if ((socketfd=socket(AF_INET, SOCK_STREAM, 0))==-1)
  {
        printf("socket() error\n");
        exit(1);
  }
//connect
  bzero(&server,sizeof(server));
  server.sin_family = AF_INET;
  server.sin_port = htons(PORT);
  server.sin_addr = *((struct in_addr *)he->h_addr);    
  if(connect(socketfd, (struct sockaddr *)&server,sizeof(struct sockaddr))==-1)
  {
        printf("connect() error\n");
        exit(1);
  }

  process(stdin,socketfd);
//close
  close(socketfd);        
}

void process(FILE *fp, int sockfd)
{
  char  sendline[MAXDATASIZE], recvline[MAXDATASIZE];
  int numbytes;

  printf("Connected to server. \n");
//send name
  printf("Input name : ");
  if (fgets(sendline, MAXDATASIZE, fp) == NULL) //在这里fp是stdin
  {
         printf("\nExit.\n");
         return;
  }
  send(sockfd, sendline, strlen(sendline),0);
//send sendline
  while (getMessage(sendline, MAXDATASIZE, fp) != NULL)
  {
         send(sockfd, sendline, strlen(sendline),0);
//recv
         if ((numbytes = recv(sockfd, recvline, MAXDATASIZE,0)) == 0)
         {
                 printf("Server terminated.\n");
                 return;
         }
         recvline[numbytes]='\0';
         printf("Server Message: %s\n",recvline);
  }
  printf("\nExit.\n");
}

char* getMessage(char* sendline,int len, FILE* fp)
{//其实就是一个fgets
  printf("Input string to server:");
  return(fgets(sendline, MAXDATASIZE, fp));
}