Linux下TCP和UDP编程实例

TCP:



///

服务器端:

/*****************************************

*TCP服务器端步骤:

*创建套接字  socket()

*绑定套接字  bind()  ------> listen()

*设置套接字为监听模式,进入被动接受连接请求状态

*接受请求,建立连接 recv()

*读写数据  send()

*终止连接   close()

******************************************/

#include <stdio.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <arpa/inet.h>

#define BUFSIZE 1000

int

main (int argc, char *argv[])

{

  int s;

  int fd;

  int len;

  struct sockaddr_in my_addr;

  struct sockaddr_in remote_addr;

  int sin_size;

  char buf[BUFSIZE];

  memset (&my_addr, 0, sizeof (my_addr));

  my_addr.sin_family = AF_INET;

  my_addr.sin_addr.s_addr = INADDR_ANY;

  my_addr.sin_port = htons (8000);

  if ((s = socket (PF_INET, SOCK_STREAM, 0)) < 0)

    {

      perror ("socket");

      return 1;

    }

  if (bind (s, (struct sockaddr *) &my_addr, sizeof (struct sockaddr)) < 0)

    {

      perror ("bind");

      return 1;

    }

  listen (s, 5);

  sin_size = sizeof (struct sockaddr_in);

  if ((fd = accept (s, (struct sockaddr *) &remote_addr, &sin_size)) < 0)

    {

      perror ("accept");

      return 1;

    }

  printf ("accept client %s\n", inet_ntoa (remote_addr.sin_addr));

  len = send (fd, "Welcome to my serve\n", 21, 0);

  while ((len = recv (fd, buf, BUFSIZE, 0)) > 0)

    {

      buf[len] = '\0';

      printf ("%s\n", buf);

      if (send (fd, buf, len, 0) < 0)

{

 perror ("write");

 return 1;

}

    }

  close (fd);

  close (s);

  return 0;

}

 

客户端:

/****************************************

*TCP客户端步骤:

*创建套接字socket

*与远程服务程序连接connect

*读写数据recv,send

*终止连接close

*****************************************/

#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>

#define BUFSIZE 1000

int

main (int argc, char *argv[])

{

  int s;

  int len;

  struct sockaddr_in remote_addr;

  char buf[BUFSIZE];

  memset (&remote_addr, 0, sizeof (remote_addr));

  remote_addr.sin_family = AF_INET;

  remote_addr.sin_addr.s_addr = inet_addr ("192.168.127.135");

  remote_addr.sin_port = htons (8000);

  if ((s = socket (PF_INET, SOCK_STREAM, 0)) < 0)

    {

      perror ("socket");

      return 1;

    }

  if (connect (s, (struct sockaddr *) &remote_addr, sizeof (struct sockaddr)) <

      0)

    {

      perror ("connect");

      return 1;

    }

  printf ("connected to server\n");

  len = recv (s, buf, BUFSIZE, 0);

  buf[len] = '\0';

  printf ("%s", buf);

  while (1)

    {

      printf ("Enter string to send:");

      scanf ("%s", buf);

      if (!strcmp (buf, "quit"))

{

 break;

}

      len = send (s, buf, strlen (buf), 0);

      len = recv (s, buf, BUFSIZE, 0);

      buf[len] = '\0';

      printf ("received:%s\n", buf);

    }

  close (s);

  return 0;

}

/

UDP

服务器端:

/************************************

*服务器端实现步骤:

*建立UDP套接字;socket

*绑定套接字到特定地址;bind

*等待并接收客户端信息;recvfrom

*处理客户端请求;

*发信息回客户端;sendto

*关闭套接字close

****************************************/

#include <stdio.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <arpa/inet.h>

#define BUFSIZE 1000

int

main (int argc, char *argv[])

{

  int s;

  int fd;

  int len;

  struct sockaddr_in my_addr;

  struct sockaddr_in remote_addr;

  int sin_size;

  char buf[BUFSIZE];

  memset (&my_addr, 0, sizeof (my_addr));

  my_addr.sin_family = AF_INET;

  my_addr.sin_addr.s_addr = INADDR_ANY;

  my_addr.sin_port = htons (8000);

  if ((s = socket (PF_INET, SOCK_DGRAM, 0)) < 0)

    {

      perror ("socket");

      return 1;

    }

  if (bind (s, (struct sockaddr *) &my_addr, sizeof (struct sockaddr)) < 0)

    {

      perror ("bind");

      return 1;

    }

  sin_size = sizeof (struct sockaddr_in);

  printf ("waiting for a packet...\n");

  if ((len =

       recvfrom (s, buf, BUFSIZE, 0, (struct sockaddr *) &remote_addr,

&sin_size)) < 0)

    {

      perror ("recvfrom");

      return 1;

    }

  printf ("received packet from %s:\n", inet_ntoa (remote_addr.sin_addr));

  buf[len] = '\0';

  printf ("contents:%s\n", buf);

  close (s);

  return 0;

  return 0;

}

客户端:

/*************************************

* 建立UDP套接字;socket

*发送信息给服务器;sendto

*接收来自服务器的信息;recvfrom

*关闭套接字close

***************************************/

#include <stdio.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <arpa/inet.h>

#define BUFSIZE 1000

 

int

main (int argc, char *argv[])

{

  int s;

  int len;

  struct sockaddr_in remote_addr;

  int sin_size;

  char buf[BUFSIZE];

  memset (&remote_addr, 0, sizeof (remote_addr));

  remote_addr.sin_family = AF_INET;

  remote_addr.sin_addr.s_addr = inet_addr ("192.168.127.135");

  remote_addr.sin_port = htons (8000);

  if ((s = socket (PF_INET, SOCK_DGRAM, 0)) < 0)

    {

      perror ("socket");

      return 1;

    }

  strcpy (buf, "This is a test message");

  printf ("sending:%s\n", buf);

  sin_size = sizeof (struct sockaddr_in);

  if ((len =

       sendto (s, buf, strlen (buf), 0, (struct sockaddr *) &remote_addr,

      sizeof (struct sockaddr))) < 0)

    {

      perror ("recvfrom");

      return 1;

    }

  close (s);

  return 0;

}

///

函数原型:

1、htons();//将short类型的值从主机字节序转换为网络字节序

2、inet_addr();//将IP地址字符串转换为long类型的网络字节序

3、gethostbyname();//获得与该域名对应的IP地址

4、inet_ntoa();//将long类型的网络字节序转换成IP地址字符串

5、int socket(int domain,int type,int protocol);

  domain指明所使用的协议族,通常为AF_INET,表示互联网协议族(TCP/IP协议族);

  type参数指定socket的类型;

  protocol通常赋值“0”,表示默认为TCP/IP协议

  socket()调用返回一个整型socket描述符,在以后的调用中使用。

6、int bind(int sockfd, struct sockaddr *my_addr, int addrlen);

  sockfd:是调用socket函数返回的socket描述符

  my_addr:是一个指向包含有本机IP地址及端口号等信息的sockaddr类型的指针

  addrlen:代表my_addr指向的地址结构的长度,可设置为 sizeof(struct sockaddr)

7、int listen(int sockfd, int backlog);

  sockfd:Socket系统调用返回的socket 描述符

  backlog:指定在请求队列中允许的最大请求数,进入的连接请求将在队列中等待accept()它们。Backlog对队列中等待服务的请求的数目进行了限制,大多数系统缺省值为20。如果一个服务请求到来时,输入队列已满,该socket将拒绝连接请求,客户将收到一个出错信息.

8、int accept(int sockfd, void *addr, int *addrlen);

  sockfd:被监听的socket描述符

  addr:一个指向sockaddr_in变量的指针,该变量用来存放提出连接请求服务的主机的信息(某台主机从某个端口发出该请求)

  addrlen:一个指向值为sizeof(struct sockaddr_in)的整型指针变量.

9、int sendto(int sockfd, const void *msg,int len,unsigned int flags,const struct sockaddr *to, int tolen);

  flags:调用方式标志,通常取0

  to:目地机的IP地址和端口号信息

  tolen:赋值为sizeof (struct sockaddr)

  返回值:返回实际发送的数据字节长度或在出现发送错误时返回-1

10、int recvfrom( int sockfd,   void *buf,  int len,  unsigned int flags,   struct sockaddr *from,int *fromlen);

  flags:调用操作方式,通常取0

  from是一个struct sockaddr类型的变量,该变量保存源机的IP地址及端口号

  fromlen常置为sizeof (struct sockaddr)。当recvfrom()返回时,

  fromlen包含实际存入from中的数据字节数

  返回值:返回接收到的字节数或当出现错误时返回-1,并置相应的errno

11、int send( SOCKET s, const char FAR *buf, int len, int flags );

  不论是客户还是服务器应用程序都用send函数来向TCP连接的另一端发送数据。客户程序一般用send函数向服务器发送请求,而服务器则通常用send函数来向客户程序发送应答。

  该函数的第一个参数指定发送端套接字描述符;

  第二个参数指明一个存放应用程序要发送数据的缓冲区;

  第三个参数指明实际要发送的数据的字节数;

  第四个参数一般置0。

12、int recv( SOCKET s, char FAR *buf, int len, int flags);

  不论是客户还是服务器应用程序都用recv函数从TCP连接的另一端接收数据。该函数的第一个参数指定接收端套接字描述符;

  第二个参数指明一个缓冲区,该缓冲区用来存放recv函数接收到的数据;

  第三个参数指明buf的长度;

  第四个参数一般置0。

///



Linux网络编程一步一步学-UDP方式广播通讯

和前一篇文章<Linux网络编程一步一步学-UDP方式点对点通讯>一样,只是在客户端源代码里加一行设置socket属性为广播方式即可。需要加的一句是:
setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &yes, sizeof(yes));
源代码变成下面的:
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
/*********************************************************************
*filename: broadc-udpclient.c
*purpose: 基本编程步骤说明,演示了UDP编程的广播客户端编程步骤
*tidied by: zhoulifa(zhoulifa@163.com) 周立发(http://zhoulifa.bokee.com)
Linux爱好者 Linux知识传播者 SOHO族 开发者 最擅长C语言
*date time:2007-01-24 21:30:00
*Note: 任何人可以任意复制代码并运用这些文档,当然包括你的商业用途
* 但请遵循GPL
*Thanks to: Google.com
*Hope:希望越来越多的人贡献自己的力量,为科学技术发展出力
* 科技站在巨人的肩膀上进步更快!感谢有开源前辈的贡献!
*********************************************************************/
int main(int argc, char **argv)
{
struct sockaddr_in s_addr;
int sock;
int addr_len;
int len;
char buff[128];
int yes;
/* 创建 socket */
if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
perror("socket");
exit(errno);
} else
printf("create socket.\n\r");
/* 设置通讯方式对广播,即本程序发送的一个消息,网络上所有主机均可以收到 */
yes = 1;
setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &yes, sizeof(yes));
/* 唯一变化就是这一点了 */
/* 设置对方地址和端口信息 */
s_addr.sin_family = AF_INET;
if (argv[2])
s_addr.sin_port = htons(atoi(argv[2]));
else
s_addr.sin_port = htons(7838);
if (argv[1])
s_addr.sin_addr.s_addr = inet_addr(argv[1]);
else {
printf("消息必须有一个接收者!\n");
exit(0);
}
/* 发送UDP消息 */
addr_len = sizeof(s_addr);
strcpy(buff, "hello i'm here");
len = sendto(sock, buff, strlen(buff), 0,
(struct sockaddr *) &s_addr, addr_len);
if (len 编译这个程序用下列命令:
gcc -Wall broadc-udpclient.c -o client
运行程序用下列命令:
./client 192.168.0.255 7838
就会往192.168.0网络内所有主机发消息。其它主机如果运行了服务端:
./server 自己的IP地址 7838
则都会收到上述客户端发的消息了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值