linux网络编程tcp udp聊天室,Linux网络编程一步一步学-TCP/UDP编程介绍[转]

通常我们在说到网络编程时默认是指TCP编程,即用前面提到的socket函数

创建一个socket用于TCP通讯,函数参数我们通常填为SOCK_STREAM。即socket(PF_INET,

SOCK_STREAM, 0),这表示建立一个socket用于流式网络通讯。

通过查看socket的man手册可以看到socket函数的第一个参数的值可以为下面这些值:

Name Purpose

PF_UNIX,

PF_LOCAL Local communication

PF_INET IPv4 Internet protocols

PF_INET6 IPv6 Internet protocols

PF_IPX IPX - Novell protocols

PF_NETLINK Kernel user interface device

PF_X25 ITU-T X.25 / ISO-8208 protocol

PF_AX25 Amateur radio AX.25 protocol

PF_ATMPVC Access to raw ATM PVCs

PF_APPLETALK Appletalk

PF_PACKET Low level packet interface

第二个参数支持下列几种值:

SOCK_STREAM

Provides sequenced, reliable, two-way, connection-based byte

streams. An out-of-band data transmission mechanism may be

sup‐

ported.

SOCK_DGRAM

Supports datagrams (connectionless, unreliable messages of a fixed

maximum length).

SOCK_SEQPACKET

Provides a sequenced, reliable, two-way connection-based data

transmission path for datagrams of fixed maximum length; a

con‐

sumer is required to read an entire packet with each read system

call.

SOCK_RAW

Provides raw network protocol access.

SOCK_RDM

Provides a reliable datagram layer that does not guarantee

ordering.

SOCK_PACKET

Obsolete and should not be used in new programs; see

packet(7).

从这里可以看出,SOCK_STREAM这种的特点是面向连接的,即每次收发数据之前必须通过connect建立连接,也是双向的,即任何一方都可以收发数据,协议本身提供了一些保障机制保证它是可靠的、有序的,即每个包按照发送的顺序到达接收方。

而SOCK_DGRAM这种是User Datagram

Protocol协议的网络通讯,它是无连接的,不可靠的,因为通讯双方发送数据后不知道对方是否已经收到数据,是否正常收到数据。任何一方建立一个

socket以后就可以用sendto发送数据,也可以用recvfrom接收数据。根本不关心对方是否存在,是否发送了数据。它的特点是通讯速度比较

快。大家都知道TCP是要经过三次握手的,而UDP没有。

基于上述不同,UDP和TCP编程步骤也有些不同,如下:

TCP编程的服务器端一般步骤是:

1、创建一个socket,用函数socket();

2、设置socket属性,用函数setsockopt(); * 可选

3、绑定IP地址、端口等信息到socket上,用函数bind();

4、开启监听,用函数listen();

5、接收客户端上来的连接,用函数accept();

6、收发数据,用函数send()和recv(),或者read()和write();

7、关闭网络连接;

8、关闭监听;

TCP编程的客户端一般步骤是:

1、创建一个socket,用函数socket();

2、设置socket属性,用函数setsockopt();* 可选

3、绑定IP地址、端口等信息到socket上,用函数bind();* 可选

4、设置要连接的对方的IP地址和端口等属性;

5、连接服务器,用函数connect();

6、收发数据,用函数send()和recv(),或者read()和write();

7、关闭网络连接;

与之对应的UDP编程步骤要简单许多,分别如下:

UDP编程的服务器端一般步骤是:

1、创建一个socket,用函数socket();

2、设置socket属性,用函数setsockopt();* 可选

3、绑定IP地址、端口等信息到socket上,用函数bind();

4、循环接收数据,用函数recvfrom();

5、关闭网络连接;

UDP编程的客户端一般步骤是:

1、创建一个socket,用函数socket();

2、设置socket属性,用函数setsockopt();* 可选

3、绑定IP地址、端口等信息到socket上,用函数bind();* 可选

4、设置对方的IP地址和端口等属性;

5、发送数据,用函数sendto();

6、关闭网络连接;

实例:

server.c

#include

#include

#include

#include

#include

#include

#include

#define SERVER_PORT 8003

#define MSG_BUF_SIZE 512

int port = SERVER_PORT ;

char *hostname = "127.0.0.1";

int main(int argc , char *argv[])

{

int sinlen

;

int port = SERVER_PORT;

char message[MSG_BUF_SIZE];

int sockfd

;

struct sockaddr_in sin ;

struct hostent *server_host_name;

if ((sockfd = socket(PF_INET ,SOCK_DGRAM,0))== -1)

{

fprintf(stderr, "socket

error");

exit(1);

}

server_host_name = gethostbyname("127.0.0.1");

bzero(&sin ,sizeof(sin));

sin.sin_family = AF_INET;

sin.sin_addr.s_addr = htonl(INADDR_ANY);

sin.sin_port = htons(port);

if ( (bind(sockfd, (struct sockaddr *)&sin

,sizeof(sin)) ) == -1)

{

fprintf(stderr, "socket

error");

exit(1);

}

while (1)

{

memset(

&message , 0 , sizeof(message));

sinlen = sizeof(sin);

//recvfrom(sockfd ,message ,

512 ,0 ,(struct sockaddr *)&sin

,&sinlen);

recvfrom(sockfd ,message , 512

,0 ,NULL,NULL);

printf("\nData come from

server . \n %s\n ",message);

if

(strncmp(message,"over",4)==0)

{

break;

}

}

//close(sockfd);

exit(0);

}

client.c

#include

#include

#include

#include

#include

#include

#include

#include

#define SERVER_PORT 8003

#define MSG_BUF_SIZE 512

int port = SERVER_PORT ;

int main(int argc , char *argv[])

{

int

sockfd;

int count = 0;

int flag ;

char buf[MSG_BUF_SIZE];

struct sockaddr_in address;

if ((sockfd = socket(AF_INET,SOCK_DGRAM,0)) == -1)

{

fprintf( stderr, "socket

error");

exit(1);

}

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

address.sin_family = AF_INET;

address.sin_addr.s_addr = inet_addr("127.0.0.1");

address.sin_port = htons(port);

flag = 1;

do

{ int n = 0;

memset( &buf ,

0 , sizeof(buf));

if((n = read(STDIN_FILENO,

buf, MSG_BUF_SIZE)) > 0){

sendto(sockfd, buf , sizeof(buf) ,0 ,(struct sockaddr

*)&address ,sizeof(address));

}

if

(strncmp(buf,"over",4)==0)

{

flag = 0

;

}

}while (flag);

return

0;

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值