首页 > 其他 > 详细

Unix网络编程之基本TCP套接字编程(上)

时间:2014-08-01 23:15:02      阅读:455      评论:0      收藏:0      [点我收藏+]

TCP客户/服务器实例

 

服务器程序

 

#include "unp.h"
int main(int argc, char **argv)
{
	int listenfd, connfd;
	pid_t childpid;
	socklen_t clilen;
	struct sockaddr_in cliaddr, servaddr;
	listenfd = Socket(AF_INET, SOCK_STREAM, 0); //1
	bzero(&servaddr, sizeof(servaddr));         //2 
	servaddr.sin_family = AF_INET;              
	servaddr.sin_addr.s_addr = htonl(INADDR_ANY);  //3
	servaddr.sin_port = htons(SERV_PORT);
	Bind(listenfd, (SA*) &servaddr, sizeof(servaddr));  //4
	Listen(listenfd, LISTENQ);  //5
	for(;;)
	{
		clilen = sizeof(cliaddr);
		connfd = Accept(listenfd,(SA*) &cliaddr, &clilen);  //6
		if((childpid = Fork())== 0)     //7
		{
			Close(listenfd);
			str_echo(connfd);
			exit(0);
		}
		Close(connfd);             //8
	}
}


 

客户端程序

 

#include "unp.h"
int main(int argc, char** argv)
{
	int sockfd;
	struct sockaddr_in servaddr;
	if (argc != 2)
		err_quit("usage:tcpcli<IP>");
	sockfd = Socket(AF_INET, SOCK_STREAM, 0);
	bzero(&servaddr, sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_port = htons(SERV_PORT);
	Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);    //9
	Connect(sockfd, (SA*) &servaddr, sizeof(servaddr));  //10
	str_cli(stdin, sockfd);
	exit(0);
}


 

测试结果

 

1.先执行服务器端程序,此时服务器处于监听状态

bubuko.com,布布扣

 

 

2.再执行客户端程序。

客户端从标准输入获得内容,传递给服务器,又从服务器收回原数据,并显示在屏幕上。

bubuko.com,布布扣

 

 

 

 3.当多个客户端同时连接服务器时,也可以照常工作

bubuko.com,布布扣

 

 

 

 

实例中使用的套接字介绍

 

socket函数

 

作用:

 

指定期望的通信协议类型(使用ipv4或ipv6 Tcp或Udp等)

 

使用:

 

#include<sys/socket.h>

int socket(int family, int type, int protocol);  //若成功则返回非负描述符

 

参数介绍:

 

family参数为协议族,包括:

AF_INET        IPv4协议

AF_INET6      IPv6协议

AF_LOCAL    Unix域协议

AF_ROUTE    路由套接字

AF_KEY          密钥套接字

 

type参数指明套接字类型,包括:

SOCK_STREAM          字节流套接字

SOCK_DGRAM           数据报套接字

SOCK_SEQPACKET    有序分组套接字

SOCK_RAW                原始套接字

 

 

protocol参数应设为某个协议类型常值,包括:

IPPROTO_CP       TCP传输协议

IPPROTO_UDP    UDP传输协议

IPPROTO_SCTP   SCTP传输协议

 

或者设为0,以选择给定family和type组合之后的默认值。

 

然而,并非所有套接字family和type的组合都是有效的。

bubuko.com,布布扣

 

 

然而TCP是一个字节流协议,仅支持SOCK_STREAM套接字。

 

 

 

connect函数

 

作用:

 

建立与TCP服务器的连接。

 

使用:

 

#include<sys/socket.h>

int connect(int sockfd, const struct sockaddr *servaddr, socklen_t addrlen);   //若成功则返回非负

 

参数说明:

 

第一个参数为客户为参与通信自身建立起来的套接字描述符(socket函数返回的)。

第二个参数为指向服务器地址结构的指针,服务器地址结构必须包含服务器的IP地址和端口号。

第三个参数为该地址结构的大小。

 

按照TCP状态图,connect函数导致当前套接字从CLOSED状态(socket创建后即为该状态)转移到SYN_SENT状态

若成功则再转移到ESTABLISHED状态。若失败则该套接字不再可用。

 

 

 

 

bind函数

 

作用:

 

把本地协议地址赋予一个套接字。对于TCP,bind函数可以指定一个端口号,或指定一个IP,也可以两者都指定或两种都不指定。

 

使用:

 

#include<sys/socket.h>

int bind(int sockfd, const struct sockaddr* myaddr, socklen_t addrlen);

 

 

 

listen函数

 

作用:

 

仅由TCP服务器调用,把未连接的套接字转换成一个被动套接字,指示内核应接受向该套接字的连接请求,并规定了

套接字排队的最大连接个数。

 

使用:

 

#include<sys/socket.h>

int listen(int sockfd, int backlog);

 

 

 

accept函数

 

作用:

 

由TCP服务器调用,用于从已完成连接队列队头返回下一个已完成连接。如果已完成连接队列为空,那么进程进入睡眠。

 

使用:

 

#include<sys/socket.h>

int accept(int sockfd, struct sockaddr* cliaddr, socklen_t *addrlen);

 

参数说明:

 

clicaddr 和 addrlen用来返回已连接的对端进程(客户)的协议地址。

 

 

如果accept成功,那么其返回值是由内核自动生成的一个全新的描述符,代表与客户的TCP连接。在讨论accept函数

时,我们称它的第一个参数为监听套接字描述符(由socket创建,随后用做bind和listen的第一个参数的描述符),

称它的返回值为已连接套接字描述符。

 

一个服务器通常仅仅创建一个监听套接字,它在服务器的生命周期一直存在。内核为每个由服务器进程接受的客户连

接创建一个已连接套接字(TCP三次握手已经完成)。当服务器完成对某个给定客户的服务时,相应的已连接套接字

就被关闭。

 

如果我们对客户进程的协议地址不感兴趣,那么可以把cliaddr和addrlen均置为空指针。

 

 

 

fork和exec函数

 

使用:

 

#include<unistd.h>

pid_t fork(void);

 

fork理解最困难的地方在于调用它一次,它却返回两次。

它在调用进程(父进程)中返回一次,返回值是子进程的ID号。在子进程又返回一次,返回值是0。因此返回值

本身告知当前是子进程还是父进程。

 

父进程中调用fork之前打开的所有描述符在fork返回之后由子进程分享。我们看到网络服务器利用了这个特性:父

进程调用accept之后调用fork。所接受的已连接套接字随后就在父进程与子进程之间共享。

 

 

 

close函数

 

作用:

 

关闭套接字,终止TCP连接。

 

使用:

 

#include<unistd.h>

int close(int sockfd);

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Unix网络编程之基本TCP套接字编程(上),布布扣,bubuko.com

Unix网络编程之基本TCP套接字编程(上)

原文:http://blog.csdn.net/wangxiaobupt/article/details/38340495

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!