- 浏览: 1525450 次
- 性别:
- 来自: 杭州
文章分类
- 全部博客 (525)
- SEO (16)
- JAVA-EE-Hibernate (6)
- JAVA-EE-Struts (29)
- JAVA-EE-Spring (15)
- Linux (37)
- JAVA-SE (29)
- NetWork (1)
- CMS (14)
- Semantic Research (3)
- RIA-Flex (0)
- Ajax-Extjs (4)
- Ajax-Jquery (1)
- www.godaddy.com (0)
- SSH (34)
- JavaScript (6)
- SoftwareEngineer (9)
- CMMI (0)
- IDE-Myeclipse (3)
- PHP (1)
- Algorithm (3)
- C/C++ (18)
- Concept&Items (2)
- Useful WebSite (1)
- ApacheServer (2)
- CodeReading (1)
- Socket (2)
- UML (10)
- PowerDesigner (1)
- Repository (19)
- MySQL (3)
- SqlServer (0)
- Society (1)
- Tomcat (7)
- WebService (5)
- JBoss (1)
- FCKeditor (1)
- PS/DW/CD/FW (0)
- DesignPattern (11)
- WebSite_Security (1)
- WordPress (5)
- WebConstruction (3)
- XML|XSD (7)
- Android (0)
- Project-In-Action (9)
- DatabaseDesign (3)
- taglib (7)
- DIV+CSS (10)
- Silverlight (52)
- JSON (7)
- VC++ (8)
- C# (8)
- LINQ (1)
- WCF&SOA (5)
- .NET (20)
- SOA (1)
- Mashup (2)
- RegEx (6)
- Psychology (5)
- Stock (1)
- Google (2)
- Interview (4)
- HTML5 (1)
- Marketing (4)
- Vaadin (2)
- Agile (2)
- Apache-common (6)
- ANTLR (0)
- REST (1)
- HtmlAnalysis (18)
- csv-export (3)
- Nucth (3)
- Xpath (1)
- Velocity (6)
- ASP.NET (9)
- Product (2)
- CSS (1)
最新评论
-
lt26w:
理解成门面模式应该比较容易明白吧
FacadePattern-Java代码实例讲解 -
lt26w:
看下面的例子比较明白.
FacadePattern-Java代码实例讲解 -
javaloverkehui:
这也叫文档,别逗我行吗,也就自己看看。
HtmlCleaner API -
SE_XiaoFeng:
至少也应该写个注释吧。
HtmlCleaner API -
jfzshandong:
...
org.springframework.web.filter.CharacterEncodingFilter 配置
socket()
bind()
一旦你有了一个套接口以后,下一步就是把套接口绑定到本地计算机的某一个端口上。但如果你只想使用
connect()
则无此必要。
我们使用系统调用
socket()
来获得文件描述符:
#include<sys/types.h>
#include<sys/socket.h>
int socket(int domain,int type,int protocol);
第一个参数
domain
设置为
“AF_INET”
。
第二个参数是套接口的类型:
SOCK_STREAM
或
SOCK_DGRAM
。第三个参数设置为
0
。
系统调用
socket()
只返回一个套接口描述符,如果出错,则返回
-1
。
下面是系统调用
bind()
的使用方法:
#include<sys/types.h>
#include<sys/socket.h>
intbind(int sockfd,struct sockaddr*my_addr,int addrlen);
第一个参数
sockfd
是由
socket()
调用返回的套接口文件描述符。
第二个参数
my_addr
是指向数据结构
sockaddr
的指针。数据结构
sockaddr
中包括了关于你的地址、端口和
IP
地址的信息。
第三个参数
addrlen
可以设置成
sizeof(structsockaddr)
。
下面是一个例子:
#include<string.h> #include<sys/types.h> #include<sys/socket.h> #defineMYPORT3490 main() { int sockfd; struct sockaddr_inmy_addr; sockfd=socket(AF_INET,SOCK_STREAM,0);/*do someerror checking!*/ my_addr.sin_family=AF_INET;/*hostbyteorder*/ my_addr.sin_port=htons(MYPORT);/*short,network byte order*/ my_addr.sin_addr.s_addr=inet_addr("132.241.5.10"); bzero(&(my_addr.sin_zero),8);/*zero the rest of the struct*/ /*don't forget your error checking for bind():*/ bind(sockfd,(struct sockaddr*)&my_addr,sizeof(struct sockaddr)); ...
如果出错,
bind()
也返回
-1
。
connect()
系统调用
connect()
的用法如下:
listen()
accept()
如果你使用
connect()
系统调用,那么你不必知道你使用的端口号。当你调用
connect()
时,它检查套接口是否已经绑定,如果没有,它将会分配一个空闲的端口。
#include<sys/types.h>
#include<sys/socket.h>
int connect(int sockfd,struct sockaddr* serv_addr,int addrlen);
第一个参数还是套接口文件描述符,它是由系统调用
socket()
返回的。
第二个参数是
serv_addr
是指向数据结构
sockaddr
的指针,其中包括目的端口和
IP
地址。
第三个参数可以使用
sizeof(structsockaddr)
而获得。
下面是一个例子:
#include<string.h>
#include<sys/types.h>
#include<sys/socket.h>
#defineDEST_IP"132.241.5.10"
#defineDEST_PORT23
main()
{
intsockfd;
structsockaddr_indest_addr;/*will hold the destination addr*/
sockfd=socket(AF_INET,SOCK_STREAM,0);/*do some error checking!*/
dest_addr.sin_family=AF_INET;/*hostbyteorder*/
dest_addr.sin_port=htons(DEST_PORT);/*short,network byte order*/
dest_addr.sin_addr.s_addr=inet_addr(DEST_IP);
bzero(&(dest_addr.sin_zero),8);/*zero the rest of the struct*/
/*don'tforgettoerrorchecktheconnect()!*/
connect(sockfd,(structsockaddr*)&dest_addr,sizeof(struct sockaddr));
...
同样,如果出错,
connect()
将会返回
-1
。
如果你希望不连接到远程的主机,也就是说你希望等待一个进入的连接请求,然后再处理它们。这样,你通过首先调用
listen()
,然后再调用
accept()
来实现。
系统调用
listen()
的形式如下:
intl isten(int sockfd,int backlog);
第一个参数是系统调用
socket()
返回的套接口文件描述符。
第二个参数是进入队列中允许的连接的个数。进入的连接请求在使用系统调用
accept()
应答之前要在进入队列中等待。这个值是队列中最多可以拥有的请求的个数。大多数系统的缺省设置为
20
。你可以设置为
5
或者
10
。当出错时,
listen()
将会返回
-1
值。
当然,在使用系统调用
listen()
之前,我们需要调用
bind()
绑定到需要的端口,否则系统内核将会让我们监听一个随机的端口。所以,如果你希望监听一个端口,下面是应该使用的系统调用的顺序:
socket();
bind();
listen();
/*accept()goeshere*/
系统调用
accept()
比较起来有点复杂。在远程的主机可能试图使用
connect()
连接你使用
listen()
正在监听的端口。但此连接将会在队列中等待,直到使用
accept()
处理它。调用
accept()
之后,将会返回一个全新的套接口文件描述符来处理这个单个的连接。这样,对于同一个连接
来说,你就有了两个文件描述符。原先的一个文件描述符正在监听你指定的端口,新的文件描
述符可以用来调用
send()
和
recv()
。
调用的例子如下:
#include<sys/socket.h>
intaccept(intsockfd,void*addr,int*addrlen);
第一个参数是正在监听端口的套接口文件描述符。第二个参数
addr
是指向本地的数据结构
sockaddr_in
的指针。调用
connect()
中的信息将存储在这里。通过它你可以了解哪个主机在哪个
端口呼叫你。第三个参数同样可以使用
sizeof(structsockaddr_in)
来获得。
如果出错,
accept()
也将返回
-1
。下面是一个简单的例子:
#include<string.h> #include<sys/types.h> #include<sys/socket.h> #defineMYPORT3490/*theportuserswillbeconnectingto*/ #defineBACKLOG10/*howmanypendingconnectionsqueuewillhold*/ main() { intsockfd,new_fd;/*listenonsock_fd,newconnectiononnew_fd*/ structsockaddr_inmy_addr;/*myaddressinformation*/ structsockaddr_intheir_addr;/*connector'saddressinformation*/ intsin_size; sockfd=socket(AF_INET,SOCK_STREAM,0);/*dosomeerrorchecking!*/ my_addr.sin_family=AF_INET;/*hostbyteorder*/ my_addr.sin_port=htons(MYPORT);/*short,networkbyteorder*/ my_addr.sin_addr.s_addr=INADDR_ANY;/*auto-fillwithmyIP*/ bzero(&(my_addr.sin_zero),8);/*zerotherestofthestruct*/ /*don'tforgetyourerrorcheckingforthesecalls:*/ bind(sockfd,(structsockaddr*)&my_addr,sizeof(structsockaddr)); listen(sockfd,BACKLOG); sin_size=sizeof(structsockaddr_in); new_fd=accept(sockfd,&their_addr,&sin_size); ...
send()
和
recv()
sendto()
和
recvfrom()
close()
和
shutdown()
getpeername()
gethostname()
SOCKET C
程序代码
Makefile
文件
s: app_service.c
gcc -o s app_service.c
c: app_client.c
gcc -o c app_client.c
app_client.c
文件
下面,我们将可以使用新创建的套接口文件描述符
new_fd
来调用
send()
和
recv()
。
系统调用
send()
的用法如下:
int send(int sockfd,const void* msg,int len,int flags);
第一个参数是你希望给发送数据的套接口文件描述符。它可以是你通过
socket()
系统调用返回的,也可以是通过
accept()
系统调用得到的。
第二个参数是指向你希望发送的数据的指针。
第三个参数是数据的字节长度。第四个参数标志设置为
0
。
下面是一个简单的例子:
char*msg="Beejwashere!";
intlen,bytes_sent;
..
len=strlen(msg);
bytes_sent=send(sockfd,msg,len,0);
...
系统调用
send()
返回实际发送的字节数,这可能比你实际想要发送的字节数少。如果返回的字节数比要发送的字节数少,你在以后必须发送剩下的数据。当
send()
出错时,将返回
-1
。
系统调用
recv()
的使用方法和
send()
类似:
int recv(int sockfd,void* buf,int len,unsigned int flags);
第一个参数是要读取的套接口文件描述符。
第二个参数是保存读入信息的地址。
第三个参数是缓冲区的最大长度。第四个参数设置为
0
。
系统调用
recv()
返回实际读取到缓冲区的字节数,如果出错则返回
-1
。
这样使用上面的系统调用,你可以通过数据流套接口来发送和接受信息。
因为数据报套接口并不连接到远程的主机上,所以在发送数据包之前,我们必须首先给出目的地址,请看:
int sendto(int sockfd,const void* msg,int len,unsigned int flags,
conststruct sockaddr*to,inttolen);
除了两个参数以外,其他的参数和系统调用
send()
时相同。
参数
to
是指向包含目的
IP
地址和端口号的数据结构
sockaddr
的指针。
参数
tolen
可以设置为
sizeof(structsockaddr)
。
系统调用
sendto()
返回实际发送的字节数,如果出错则返回
-1
。
系统调用
recvfrom()
的使用方法也和
recv()
的十分近似:
int recvfrom(int sockfd,void* buf,int len,unsigned int flags
struct sockaddr* from,int* fromlen);
参数
from
是指向本地计算机中包含源
IP
地址和端口号的数据结构
sockaddr
的指针。
参数
fromlen
设置为
sizeof(struct sockaddr)
。
系统调用
recvfrom()
返回接收到的字节数,如果出错则返回
-1
。
你可以使用
close()
调用关闭连接的套接口文件描述符:
close(sockfd);
这样就不能再对此套接口做任何的读写操作了。
使用系统调用
shutdown()
,可有更多的控制权。它允许你在某一个方向切断通信,或者切断双方的通信:
int shutdown(int sockfd,int how);
第一个参数是你希望切断通信的套接口文件描述符。第二个参数
how
值如下:
0—Furtherreceivesaredisallowed
1—Furthersendsaredisallowed
2—Furthersendsandreceivesaredisallowed(likeclose())
shutdown()
如果成功则返回
0
,如果失败则返回
-1
。
这个系统的调用十分简单。它将告诉你是谁在连接的另一端:
#include<sys/socket.h>
int getpeername(int sockfd,struct sockaddr* addr,int* addrlen);
第一个参数是连接的数据流套接口文件描述符。
第二个参数是指向包含另一端的信息的数据结构
sockaddr
的指针。
第三个参数可以设置为
sizeof(structsockaddr)
。
如果出错,系统调用将返回
-1
。
一旦你获得了它们的地址,你可以使用
inet_ntoa()
或者
gethostbyaddr()
来得到更多的信息。
系统调用
gethostname()
比系统调用
getpeername()
还简单。它返回程序正在运行的计算机的名字。系统调用
gethostbyname()
可以使用这个名字来决定你的机器的
IP
地址。
下面是一个例子:
#include<unistd.h>
int gethostname(char*hostname,size_tsize);
如果成功,
gethostname
将返回
0
。如果失败,它将返回
-1
。
//客户端程序代码如下: #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 SERVPORT 3333 #define MAXDATASIZE 100 // 每次最大数据传输量 main(int argc, char *argv[]) { int sockfd, recvbytes; char buf[MAXDATASIZE]; struct hostent *host; struct sockaddr_in serv_addr; if (argc < 2) { fprintf(stderr,"Please enter the server's hostname!\n"); exit(1); } if ((host = gethostbyname(argv[1])) == NULL) { herror("gethostbyname出错!"); exit(1); } if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){ perror("socket创建出错!"); exit(1); } serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(SERVPORT); serv_addr.sin_addr = *((struct in_addr *)host->h_addr); bzero(&(serv_addr.sin_zero), 8); if (connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr)) == -1) { perror("connect出错!"); exit(1); } if ((recvbytes = recv(sockfd, buf, MAXDATASIZE, 0)) ==-1) { perror("recv出错!"); exit(1); } buf[recvbytes] = '\0'; printf("Received: %s",buf); close(sockfd); } /* 客户端程序首先通过服务器域名获得服务器的IP地址,然后创建一个socket,调用connect函数与服务器建立连接,连接成功之后接收从服务器发送过来的数据,最后关闭socket。 函数gethostbyname()是完成域名转换的。由于IP地址难以记忆和读写,所以为了方便,人们常常用域名来表示主机,这就需要进行域名和IP地址的转换。函数原型为: struct hostent *gethostbyname(const char *name); 函数返回为hosten的结构类型,它的定义如下: struct hostent { char *h_name; // 主机的官方域名 char **h_aliases; // 一个以NULL结尾的主机别名数组 int h_addrtype; // 返回的地址类型,在Internet环境下为AF-INET int h_length; // 地址的字节长度 char **h_addr_list; // 一个以0结尾的数组,包含该主机的所有地址 }; #define h_addr h_addr_list[0] //在h-addr-list中的第一个地址 当 gethostname()调用成功时,返回指向struct hosten的指针,当调用失败时返回-1。当调用gethostbyname时,你不能使用perror()函数来输出错误信息, 应该使用herror()函数来输出。 无连接的客户/服务器程序的在原理上和连接的客户/服务器是一样的,两者的区别在于无连接的客户/服务器中的客户一般不需要建立连接,而且在发送接收 数据时,需要指定远端机的地址。 */
app_service.c
文件
/* 面向连接的Socket实例 代码实例中的服务器通过socket连接向客户端发送字符串"Hello, you are connected!"。只要在服务器上运行该服务器软件,在客户端运行客户软件,客户端就会收到该字符串。 该服务器软件代码如下: */ #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <string.h> #include <sys/types.h> #include <netinet/in.h> #include <sys/socket.h> #include <sys/wait.h> #define SERVPORT 3333 // 服务器监听端口号 #define BACKLOG 10 // 最大同时连接请求数 main() { int sockfd, client_fd; // sock_fd:监听socket;client_fd:数据传输socket struct sockaddr_in my_addr; // 本机地址信息 struct sockaddr_in remote_addr; // 客户端地址信息 int sin_size; if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket创建出错!"); exit(1); } my_addr.sin_family = AF_INET; my_addr.sin_port = htons(SERVPORT); my_addr.sin_addr.s_addr = INADDR_ANY; bzero(&(my_addr.sin_zero), 8); if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) { perror("bind出错!"); exit(1); } if (listen(sockfd, BACKLOG) == -1) { perror("listen出错!"); exit(1); } while(1) { sin_size = sizeof(struct sockaddr_in); if ((client_fd = accept(sockfd, (void *)&remote_addr, &sin_size)) == -1) { perror("accept出错"); continue; } printf("received a connection from %s\n", inet_ntoa(remote_addr.sin_addr)); if (!fork()) { /* 子进程代码段 */ if (send(client_fd, "Hello, you are connected!\n", 26, 0) == -1) { perror("send出错!"); close(client_fd); exit(0); } } close(client_fd); } } /* 服务器的工作流程是这样的:首先调用socket函数创建一个Socket,然后调用bind函数将其与本机地址以及一个本地端口号绑定,然后调用 listen在相应的socket上监听,当accpet接收到一个连接服务请求时,将生成一个新的socket。服务器显示该客户机的IP地址,并通过新的socket向客户端发送字符串"Hello,you are connected!"。最后关闭该socket。 代码实例中的fork()函数生成一个子进程来处理数据传输部分,fork()语句对于子进程返回的值为0。所以包含fork函数的if语句是子进程代码部分,它与if语句后面的父进程代码部分是并发执行的。 */
相关推荐
Socket编程接口是软件开发中的核心部分,特别是在网络通信领域。它提供了一种标准的方法来创建、连接和通信两个或多个通过网络连接的进程。在本文中,我们将深入探讨`socket()`、`bind()`和`connect()`这三个关键的...
Linux下的Socket编程实例是使用 C/C++ 语言实现的,通过使用 socket 函数创建一个 Socket,然后调用 bind 函数将其与本机地址以及一个本地端口号绑定,最后调用 listen 函数在相应的 socket 上监听。使用 fork 函数...
Socket编程是计算机网络通信中的重要概念,主要用于实现进程间的网络通信。在本示例中,我们探讨的是如何使用Socket进行程序间的交互。Socket可以被看作是两台计算机之间的通信端点,允许它们通过网络交换数据。下面...
19. 简单的服务器:简单的服务器是SOCKET编程中的一个重要示例,用于描述服务器端的实现。 20. 简单的客户端:简单的客户端是SOCKET编程中的一个重要示例,用于描述客户端的实现。 21. 数据报套接字 Socket:数据...
这里的"windows下socket编程示例"是指使用C语言基础的Socket接口编写在Windows操作系统下的网络应用程序,而不是基于MFC(Microsoft Foundation Classes)库的CSocket类。CSocket是MFC对Winsock API的封装,而这里...
在Windows环境下进行Socket编程,通常使用C语言进行底层网络通信的实现,因为它提供了灵活且高效的方式来操作网络套接字。本示例中的"Windows环境下socket编程(C语言编写)"是一个简单的服务器-客户端通信模型,它...
Socket编程通常涉及到了解套接字(Socket)的基本概念、网络理论、各种网络编程函数以及如何处理IP地址等问题。以下是从提供的文件信息中提炼出的知识点: ### 什么是Socket Socket是应用程序进行网络通讯的一种...
综上所述,《C语言socket编程指南》是一份面向C语言程序员的网络编程参考资料,涵盖了从基础API调用到复杂网络协议实现的关键概念和函数。通过学习该指南,读者将能掌握如何使用C语言进行网络通信,并能够开发出能够...
### 基于TCP的Socket编程在VC中的应用与实现 #### 一、知识点概览 在VC(Visual C++)环境下进行网络编程时,基于TCP的socket编程是实现客户端与服务器之间通信的重要方式之一。本文将从初始化、创建socket、绑定...
本文将深入探讨Socket编程的基本概念、机制、头文件、库文件以及DLL,同时结合TCP/IP和UDP协议,提供详尽的示例程序以加深理解。 首先,Socket是一种接口,它允许程序员通过API(应用程序编程接口)与操作系统交互...
在.NET编程环境中,C#语言提供了...总结,C#异步socket接收组件和调用示例旨在教授如何使用异步Socket进行高效的数据通信,通过理解异步编程原理、回调机制以及数据处理流程,开发者可以构建出稳定且高性能的网络应用。
在本项目中,我们利用Socket编程实现了一个简单的聊天工具,这个工具是基于C++语言,并使用Microsoft Visual Studio 2008作为开发环境。对于初学者来说,这是一个很好的实践项目,可以帮助理解Socket的工作原理和...
Socket,作为网络通信的基础接口,是实现进程间、机器间通信的关键工具。本书旨在帮助开发者理解和掌握如何利用Socket进行高效、稳定、可靠的网络应用开发。 1. Socket基础: - Socket的定义:Socket是操作系统...
在IT领域,网络通信是不可或缺的一部分,而C++作为强大的编程语言,提供了丰富的库支持进行网络...压缩包中的"**C++Socket编程**"文件可能包含了详细的代码示例和步骤解析,对于学习和理解C++ socket编程非常有帮助。
Socket编程是网络编程的核心部分,它提供了一种标准的接口,使得进程间的网络通信变得更加简单。在本场景中,我们关注的是如何通过Socket实现客户端(Client)与服务器(Server)之间的单向通信。以下是关于Socket...
Winsock是Windows Socket接口的简称,它是Microsoft Windows对Berkeley Sockets API的实现,为开发者提供了跨平台的网络通信能力。本教程将围绕如何在Windows下进行基本的SOCKET编程展开。 首先,你需要了解SOCKET...
Socket编程是计算机网络通信的核心技术之一,特别是在iOS开发中,Objective-C语言的Socket实现对于构建网络应用程序至关重要。本文将深入探讨Socket编程的基本概念、工作原理以及如何在Objective-C中进行客户端和...
在Windows环境下进行C语言的Socket编程,主要是为了实现网络通信,让不同的计算机通过网络进行数据交换。Socket编程是网络编程的基础,它提供了一种标准的接口,使得开发者能够方便地建立网络连接,发送和接收数据。...