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
则都会收到上述客户端发的消息了