Linux下基于TCP/IP的socket服务器与客户端的实现

1,TCP协议说明:
  TCP协议面向连接的协议,客户端与服务器要经过"三次握手"才能建立连接,保证数据正确性,保证数据顺序

以下是本人第一次接触与的一个简单的例子,也是本人第一次Linux下TCP,socket与C的第一个例子
程序说明:
  程序支持的自定义命令有:
    open   建立与服务器的连接
    open命令格式:open <服务器的IP地址> <服务器侦听的端口>
    send   向服务器发送数据
    end命令格式:send <要发送的信息内容
    close  断开与服务器的连接
    close命令格式:close
    help   系统的帮助信息
    help命令格式:help
    exit   退出系统
    exit命令格式:exit

用C实现的服务端代码如下:
头文件Deal.h代码:
/*
* Deal.h
*
*  Created on: 2008-10-22
*      Author: root
*/
#ifndef DEAL_H_
#define DEAL_H_
#define OPEN "open"
#define SEND "send"
#define CLOSE "close"
#define HELP "help"
#define EXIT "exit"
#define FLAG "a"
void reciev_str(const char *, int);
int get_command(const char *);
#endif /* DEAL_H_ */

实现的Deal.c代码:
/*
* Deal.c
*
*  Created on: 2008-10-22
*      Author: root
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "Deal.h"
extern char flag[10];
extern char str1[1024];
extern char str2[10];
void reciev_str(const char *source,int len) {
int i, j, k, l;
k = 0, l = 0;
/*寻找第一个空格*/
for (i = 0; i < len; i++) {
  if (source == ' ') {
   k = i;
   break;
  }
}
/*寻找第二个空格*/
for (i = i + 1; i < len; i++) {
  if (source == ' ') {
   l = i;
   break;
  }
}
/*如果没有第一个空格*/
if (k == 0) {
  for (i = 0; i < len; i++) {
   flag = source;
  }
  flag = '\0';
  str1[0] = 'a';
  str1[1] = '\0';
  str2[0] = 'a';
  str2[1] = '\0';
} else /*如果有第一个空格*/{
  /*如果没有第二个空格*/
  if (l == 0) {
   for (i = 0; i < k; i++) {
    flag = source;
   }
   flag = '\0';
   for (i = i + 1, j = 0; i < len; i++, j++) {
    str1[j] = source;
   }
   str1[j] = '\0';
   str2[0] = 'a';
   str2[1] = '\0';
  } else /*如果有第三个空格*/{
   for (i = 0; i < k; i++) {
    flag = source;
   }
   flag = '\0';
   for (i = i + 1, j = 0; i < l; i++, j++) {
    str1[j] = source;
   }
   str1[j] = '\0';
   for (i = i + 1, j = 0; i < len; i++, j++) {
    str2[j] = source;
   }
   str2[j] = '\0';
  }
}
}
int get_command(const char *h) {
if (strcmp(h, OPEN) == 0) {
  return 1;
}
if (strcmp(h, SEND) == 0) {
  return 2;
}
if (strcmp(h, CLOSE) == 0) {
  return 3;
}
if (strcmp(h, HELP) == 0) {
  return 4;
}
if (strcmp(h, EXIT) == 0) {
  return 5;
}
return -1;
}

客户端主要文件Client.c代码:
/*
* Client.c
*
*  Created on: 2008-10-22
*      Author: root
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h> /*for gethostbyname*/
#include "Deal.h"
char flag[10];
char str1[1024];
char str2[10];
void open_conn(int fd, struct sockaddr *addr)
{
if (connect(fd, addr, sizeof(struct sockaddr)) == -1)
{
  perror("connected fail!");
  exit(1);
}
}
void send_msg(int nfd, char *buf, int size)
{
if (write(nfd, buf, size) == -1)
{
  perror("send fail!");
  exit(1);
}
printf("send to server successful\n");
}
void help(char *h, char *info)
{
if (strcmp(h, HELP) == 0)
{
  if (strcmp(info, FLAG) == 0)
  {
   printf("用法:help [要帮助的命令]([]里为可选项)\n");
   printf("支持的帮助命令有:\n");
   printf(" open   建立与服务器的连接。\n");
   printf(" send   向服务器发送数据。\n");
   printf(" close  断开与服务器的连接。\n");
   printf(" help   系统的帮助信息。\n");
   printf(" exit   退出系统。\n");
  }
  else if (strcmp(info, OPEN) == 0)
  {
   printf("open命令格式:open <服务器的IP地址> <服务器侦听的端口>\n");
   printf("open命令的使用方法,例如:open 127.0.0.1 1080\n");
  }
  else if (strcmp(info, SEND) == 0)
  {
   printf("send命令格式:send <要发送的信息内容>\n");
   printf("send命令的使用方法,例如:send hello\n");
  }
  else if (strcmp(info, HELP) == 0)
  {
   printf("help命令格式:help\n");
   printf("help命令的使用方法,例如:help\n");
  }
  else if (strcmp(info, CLOSE) == 0)
  {
   printf("close命令格式:close\n");
   printf("close命令的使用方法,例如:close\n");
  }
  else if (strcmp(info, EXIT) == 0)
  {
   printf("exit命令格式:exit\n");
   printf("exit命令的使用方法,例如:exit\n");
  }
}
}
int main(int argc, char **argv)
{
int sock_fd;
struct sockaddr_in serv_addr;
char buf[1024];
struct hostent *host;
int cmd;
while (1)
{
  printf(">");
  gets(buf);
  reciev_str(buf, sizeof(buf));
  cmd = get_command(flag);
  switch (cmd)
  {
  case 1:
   if ((host = gethostbyname(str1)) == NULL)
   {
    perror("gethostbyname fail!");
    continue;
   }
   serv_addr.sin_family = AF_INET;
   serv_addr.sin_port = htons(atoi(str2));
   serv_addr.sin_addr = *((struct in_addr *) host->h_addr);
   bzero(&(serv_addr.sin_zero), 8);
   if ((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
   {
    perror("socket fail!");
    continue;
   }
   open_conn(sock_fd, (struct sockaddr *) &serv_addr);
   break;
  case 2:
   send_msg(sock_fd, str1,sizeof(str1));
   break;
  case 3:
   close(sock_fd);
   break;
  case 4:
   help(flag, str1);
   break;
  case 5:
   exit(0);
   break;
  default:
   exit(1);
   break;
  }
}
}

服务器主要文件Server.c代码:
/*
* Server.c
*
*  Created on: 2008-10-22
*      Author: root
*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#define MSG_SIZE 1024
#define BACKLOG 10
#define FIRST_COMM "./TCP_Server"
#define SECOND_COMM "--port"
#define PORT "1080"

int main(int argc, char *argv[])
{
if (argc != 3 && (strcmp(argv[0], FIRST_COMM) != 0) && (strcmp(argv[1],
   SECOND_COMM) != 0) && (strcmp(argv[2], PORT) != 0))
{
  printf("please use like this:./TCP_Server --port 1080\n");
  exit(1);
}
int sock_fd, new_fd;
struct sockaddr_in serv_addr, dest_addr;
socklen_t sin_len;
int recv_byte;
char buf[MSG_SIZE];
if ((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
  perror("socket fail!");
  exit(1);
}
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(atoi(PORT));
serv_addr.sin_addr.s_addr = INADDR_ANY;
bzero(&(serv_addr.sin_zero), 8);
if (bind(sock_fd, (struct sockaddr *) &serv_addr, sizeof(struct sockaddr))
   == -1)
{
  fprintf(stderr, "bind port %s fail!\n", PORT);
  exit(1);
}
if (listen(sock_fd, BACKLOG) == -1)
{
  perror("listen fail!");
  exit(1);
}
printf("listenning......\n");
sin_len = sizeof(dest_addr);
if ((new_fd = accept(sock_fd, (struct sockaddr *) &dest_addr, &sin_len))
   == -1)
{
  perror("accept fail!");
  exit(1);
}
printf("A client has connected to me.\t%s:%d\n", inet_ntoa(
   dest_addr.sin_addr), ntohs(dest_addr.sin_port));
while (1)
{
  if ((recv_byte = read(new_fd, buf, MSG_SIZE)) < 0)
  {
   perror("read fail!");
   continue;
  }
  else if (recv_byte == 0)
  {
   printf("A current client has disconnected to me.\n");
   break;
  }
  else
  {
   buf[recv_byte] = '\0';
   printf("RECEIVE:%s\n", buf);
  }
}
close(new_fd);
close(sock_fd);
return 0;
}
<!--v:3.2-->
<!--E 文章--><!--S 翻页-->

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值