socket_tcp
2015-08-12 23:16
417 查看
socket编程需要一定的网络基础,这里就不谈论网络基础知识了。
创建socket连接的基本步骤如下:
int socket(int domain, int type, intprotocol);
根据指定的地址族、数据类型和协议来分配一个socket的描述字及其所用的资源。
domain:协议族,常用的有AF_INET、AF_INET6、AF_LOCAL、AF_ROUTE其中AF_INET代表使用ipv4地址
type:socket类型,常用的socket类型有,SOCK_STREAM、SOCK_DGRAM、SOCK_RAW、SOCK_PACKET、SOCK_SEQPACKET等
protocol:协议。常用的协议有,IPPROTO_TCP、IPPTOTO_UDP、IPPROTO_SCTP、IPPROTO_TIPC等
int bind(int sockfd, const struct sockaddr*addr, socklen_t addrlen);
把一个地址族中的特定地址赋给socket,注意,这个地址为本地的IP地址。
sockfd:socket描述字,也就是socket引用
addr:要绑定给sockfd的协议地址
addrlen:地址的长度
通常服务器在启动的时候都会绑定一个众所周知的地址(如ip地址+端口号),用于提供服务,客户就可以通过它来接连服务器;而客户端就不用指定,有系统自动分配一个端口号和自身的ip地址组合。这就是为什么通常服务器端在listen之前会调用bind(),而客户端就不会调用,而是在connect()时由系统随机生成一个。
int listen(int sockfd, int backlog);
监听socket
sockfd:要监听的socket描述字
backlog:相应socket可以排队的最大连接个数
int connect(int sockfd, const structsockaddr *addr, socklen_t addrlen);
连接某个socket
sockfd:客户端的socket描述字
addr:服务器的socket地址
addrlen:socket地址的长度
int accept(int sockfd, struct sockaddr*addr, socklen_t *addrlen);
TCP服务器监听到客户端请求之后,调用accept()函数取接收请求
sockfd:服务器的socket描述字
addr:客户端的socket地址
addrlen:socket地址的长度
ssize_t read(int fd, void *buf, size_tcount);
读取socket内容
fd:socket描述字
buf:缓冲区
count:缓冲区长度
ssize_t write(int fd, const void *buf,size_t count);
向socket写入内容,其实就是发送内容
fd:socket描述字
buf:缓冲区
count:缓冲区长度
int close(int fd);
socket标记为以关闭 ,使相应socket描述字的引用计数-1,当引用计数为0的时候,触发TCP客户端向服务器发送终止连接请求。
一个简易的聊天器
服务端:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define MAX 1024
int init_socket(const char *ipaddr,unsigned short port)
{
int s = socket(AF_INET,SOCK_STREAM,0);
if(0 > s)
{
perror("Creat socket");
return -1;
}
struct sockaddr_in addr = {
.sin_family = AF_INET,
.sin_port = htons(port),
.sin_addr = {
.s_addr = inet_addr(ipaddr),
},
};
memset(addr.sin_zero, 0, sizeof(addr.sin_zero));
if(0 > bind(s,(struct sockaddr *)&addr,sizeof(addr)))
{
perror("bind");
return -1;
}
return s;
}
int main()
{
int s;
s = init_socket("10.0.0.111",9999);
while(1)
{
if(0 > listen(s,10))
{
perror("listen");
return -1;
}
struct sockaddr addr;
socklen_t len = sizeof(addr);
int r;
char buf[MAX];
if(0 > (r=accept(s,&addr,&len)))
{
perror("accept");
return -1;
}
send(r,"hi",strlen("hi")+1,0);
while(1)
{
if(0 > recv(r,buf,MAX,0))
{
perror("recv");
close(r);
return -1;
}
printf("[Client] : %s\n",buf);
memset(buf,0,MAX);
fgets(buf,MAX,stdin);
buf[strlen(buf)-1] = 0;
send(r,buf,strlen(buf)+1,0);
sleep(1);
}
}
}
客户端:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define MAX 1024
int main(int argc,char *argv[])
{
int s = socket(AF_INET,SOCK_STREAM,0);
if(0 > s)
{
perror("Creat socket");
return -1;
}
unsigned short port = 9999;
char *ipstr = "192.168.1.1";
if(argc == 3)
{
ipstr = argv[1];
port = atoi(argv[2]);
}
struct sockaddr_in addr;
addr.sin_family = PF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = inet_addr(ipstr);
memset(addr.sin_zero, 0, sizeof(addr.sin_zero));
socklen_t len = sizeof(addr);
if(0 > connect(s, (struct sockaddr *)&addr, len)){
perror("connect");
return -1;
}
char buf[MAX] = {0};
while(strncmp(buf,"quit",4))
{
if(0 > recv(s,buf,MAX,0))
{
perror("recv");
close(s);
return -1;
}
printf("[Server] : %s\n",buf);
memset(buf,0,MAX);
fgets(buf,MAX,stdin);
buf[strlen(buf)-1] = 0;
send(s,buf,strlen(buf)+1,0);
sleep(1);
}
close(s);
return 0;
}
socket编程需要一定的网络基础,这里就不谈论网络基础知识了。
创建socket连接的基本步骤如下:
int socket(int domain, int type, intprotocol);
根据指定的地址族、数据类型和协议来分配一个socket的描述字及其所用的资源。
domain:协议族,常用的有AF_INET、AF_INET6、AF_LOCAL、AF_ROUTE其中AF_INET代表使用ipv4地址
type:socket类型,常用的socket类型有,SOCK_STREAM、SOCK_DGRAM、SOCK_RAW、SOCK_PACKET、SOCK_SEQPACKET等
protocol:协议。常用的协议有,IPPROTO_TCP、IPPTOTO_UDP、IPPROTO_SCTP、IPPROTO_TIPC等
int bind(int sockfd, const struct sockaddr*addr, socklen_t addrlen);
把一个地址族中的特定地址赋给socket,注意,这个地址为本地的IP地址。
sockfd:socket描述字,也就是socket引用
addr:要绑定给sockfd的协议地址
addrlen:地址的长度
通常服务器在启动的时候都会绑定一个众所周知的地址(如ip地址+端口号),用于提供服务,客户就可以通过它来接连服务器;而客户端就不用指定,有系统自动分配一个端口号和自身的ip地址组合。这就是为什么通常服务器端在listen之前会调用bind(),而客户端就不会调用,而是在connect()时由系统随机生成一个。
int listen(int sockfd, int backlog);
监听socket
sockfd:要监听的socket描述字
backlog:相应socket可以排队的最大连接个数
int connect(int sockfd, const structsockaddr *addr, socklen_t addrlen);
连接某个socket
sockfd:客户端的socket描述字
addr:服务器的socket地址
addrlen:socket地址的长度
int accept(int sockfd, struct sockaddr*addr, socklen_t *addrlen);
TCP服务器监听到客户端请求之后,调用accept()函数取接收请求
sockfd:服务器的socket描述字
addr:客户端的socket地址
addrlen:socket地址的长度
ssize_t read(int fd, void *buf, size_tcount);
读取socket内容
fd:socket描述字
buf:缓冲区
count:缓冲区长度
ssize_t write(int fd, const void *buf,size_t count);
向socket写入内容,其实就是发送内容
fd:socket描述字
buf:缓冲区
count:缓冲区长度
int close(int fd);
socket标记为以关闭 ,使相应socket描述字的引用计数-1,当引用计数为0的时候,触发TCP客户端向服务器发送终止连接请求。
一个简易的聊天器
服务端:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define MAX 1024
int init_socket(const char *ipaddr,unsigned short port)
{
int s = socket(AF_INET,SOCK_STREAM,0);
if(0 > s)
{
perror("Creat socket");
return -1;
}
struct sockaddr_in addr = {
.sin_family = AF_INET,
.sin_port = htons(port),
.sin_addr = {
.s_addr = inet_addr(ipaddr),
},
};
memset(addr.sin_zero, 0, sizeof(addr.sin_zero));
if(0 > bind(s,(struct sockaddr *)&addr,sizeof(addr)))
{
perror("bind");
return -1;
}
return s;
}
int main()
{
int s;
s = init_socket("10.0.0.111",9999);
while(1)
{
if(0 > listen(s,10))
{
perror("listen");
return -1;
}
struct sockaddr addr;
socklen_t len = sizeof(addr);
int r;
char buf[MAX];
if(0 > (r=accept(s,&addr,&len)))
{
perror("accept");
return -1;
}
send(r,"hi",strlen("hi")+1,0);
while(1)
{
if(0 > recv(r,buf,MAX,0))
{
perror("recv");
close(r);
return -1;
}
printf("[Client] : %s\n",buf);
memset(buf,0,MAX);
fgets(buf,MAX,stdin);
buf[strlen(buf)-1] = 0;
send(r,buf,strlen(buf)+1,0);
sleep(1);
}
}
}
客户端:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define MAX 1024
int main(int argc,char *argv[])
{
int s = socket(AF_INET,SOCK_STREAM,0);
if(0 > s)
{
perror("Creat socket");
return -1;
}
unsigned short port = 9999;
char *ipstr = "192.168.1.1";
if(argc == 3)
{
ipstr = argv[1];
port = atoi(argv[2]);
}
struct sockaddr_in addr;
addr.sin_family = PF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = inet_addr(ipstr);
memset(addr.sin_zero, 0, sizeof(addr.sin_zero));
socklen_t len = sizeof(addr);
if(0 > connect(s, (struct sockaddr *)&addr, len)){
perror("connect");
return -1;
}
char buf[MAX] = {0};
while(strncmp(buf,"quit",4))
{
if(0 > recv(s,buf,MAX,0))
{
perror("recv");
close(s);
return -1;
}
printf("[Server] : %s\n",buf);
memset(buf,0,MAX);
fgets(buf,MAX,stdin);
buf[strlen(buf)-1] = 0;
send(s,buf,strlen(buf)+1,0);
sleep(1);
}
close(s);
return 0;
}
相关文章推荐
- 图论训练总结
- 使用HttpWebRequest与HttpWebResponse抓取网页数据
- HTTP协议总结
- SharePoint 2013 通过HttpModule 管理视图权限
- unix网络编程
- (转载)Convolutional Neural Networks卷积神经网络
- HttpClientGet与HttpClientPost
- 【网络编程】简单线程池的原理和实现
- python网络编程(2)
- PXE网络装机配置和kickstart 无人值守安装
- hdu 3416 最短路+网络流(不重叠最短路径计数)
- python网络编程
- AngularJS $http Service
- TCP通讯程序设计
- twisted.http 异步访问站点
- 工具类:MD5加密
- 工具类:处理网络请求的回应
- HttpClient发送网络请求
- CentOS 6.6上使用httpd做YUM仓库
- Android--HttpURLConnection