‘壹’ 简述基于TCP和UDP的Socket编程的异同
Socket有两种主要的操作方式:面向连接的和无连接的。无连接的操作使用UDP数据报协议,这个操作不需要连接一个目的的socket,它只是简单地投出数据报,快速高效,但缺少数据安全性。面向连接的操作使用TCP协议,一个这个模式的socket必须在发送数据之前与目的地的socket取得一个连接,一旦连接建立了,socket就可以使用一个流接口:打开-读-写-关闭,所有的发送的信息都会在另一端以同样的顺序被接收,面向连接的操作比无连接的操作效率要低,但数据的安全性更高。基于TCP的socket编程是采用的流式套接字(SOCK_STREAM)。基于UDP采用的数据报套接字(SOCK_DGRAM).
流式套接字的设计是针对面向连接的网络应用,在数据传输之前需要预先建立连接,在数据传输过程中需要维持连接,在数据传输结束后需要释放连接。由于采用校验和、确认与超时等差错控制手段,因此流式套接字可以保证数据传输的正确性。
数据报套接字(SOCK_DGRAM)提供无连接的、不可靠的数据传输服务,实际上它是基于TCP/IP协议族中的UDP协议实现的。数据报套接字提供无序、有差错与有重复的数据流服务。数据报套接字的设计是针对无连接的网络应用,在数据传输之前不需要预先建立连接。由于只采用很有限的差错控制手段,因此数据报套接字无法保证数据传输的正确性。
‘贰’ 如何编写简单的socket网络程序 如何编写基于TCP协议的网络程序
下面是个人用了一个40分钟左右的时间编写的程序,在这编写过程中,非常重要的一点就是: 要理解 tcp协议编写程序的原理,即编写服务器端的过程,以及编写客户端的过程。 只要把握这两点就可以很容易编写出来了,但是要快速编写出这个程序,那么VC6.0开发工具里,最好要安装一个番茄插件,这个插件可以快速提高你的编写程序的效率,还有也要安装msdn 文档,这样在编写过程中,遇到对某个函数的参数想不全的时候,使用msdn就能快速帮你回忆了。 呵呵,如果你那一天去面试一家牛逼的公司的哇,很有可能就是 在笔试完成之后,就要进行机试了,这就完全考查出你的真正编程水平了。 能在极短时间里完成一个socket网络程序,那么就可以令面试官感到非常满意了。 不过,这个程序,还没有连接数据库,以后再继续搞了。
如果你去面试 深圳科技园 那家 伟易达 集团公司的软件工程师的哇,那么机试题目就是这个。 当时我去面试,首先进行笔试,面试官对我笔试成绩比较满意,所以就叫我留下来吃顿饭,下午进行机试。 当时我应聘岗位是Linux系统工程师C语言, 可是笔试题目,不但考核C,还考核C++,JavaScript,html。 我感觉好奇怪,心里想,好像我是应聘VC++开发那个岗位了。 于是我等到下午,他拿来机试题目之时,才真正明白,果然是他要安排我从事VC++开发了,题目就是:编写基于TCP/IP协议网络程序,并实现简单的聊天程序,而且要连接数据库。 当时我又失望了。 于是我就提出,我不想做这个题目,因为我是想应聘Linux系统C语言开发的。 就这样失望的走了。
下面是个人完全能运行的代码:
服务器端源码:
#include<stdio.h>
#include <Winsock2.h>
#pragma comment (lib,"ws2_32.lib")
int main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
return 0;
}
if ( LOBYTE( wsaData.wVersion ) != 2 ||
HIBYTE( wsaData.wVersion ) != 2 ) {
WSACleanup( );
return 0;
}
SOCKET socketServer=socket(AF_INET,SOCK_STREAM,0);
SOCKADDR_IN addrServer;
addrServer.sin_family=AF_INET;
addrServer.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
addrServer.sin_port=htons(6000);
bind(socketServer, (struct sockaddr *)&addrServer, sizeof(struct sockaddr));
listen(socketServer, 5);
SOCKADDR_IN addrClient;
int addrLen=sizeof(SOCKADDR_IN);
char sendBuf[100];
char recvBuf[100];
int i=1;
while(1)
{
printf("服务器端等待第%d个客户端连接请求...\n", i++);
SOCKET newsocketServer=accept(socketServer,(struct sockaddr *)&addrClient, &addrLen);
if(newsocketServer!=INVALID_SOCKET)
{
printf("服务器端与客户端连接成功...\n");
}
memset(sendBuf,0,100);
sprintf(sendBuf,"Welcome you to come here");
send(newsocketServer, sendBuf, strlen(sendBuf)+1,0);
memset(recvBuf,0,100);
recv(newsocketServer,recvBuf,100,0);
printf("服务器端收到信息:%s\n",recvBuf);
closesocket(newsocketServer);
}
WSACleanup();
return 0;
}
此文章来自于个人博客: 阿浪博客 http://blog.163.com/wenxianliang08@126/
客户端源码:
#include<stdio.h>
#include <Winsock2.h>
#pragma comment (lib,"ws2_32.lib")
int main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
return 0;
}
if ( LOBYTE( wsaData.wVersion ) != 2 ||
HIBYTE( wsaData.wVersion ) != 2 ) {
WSACleanup( );
return 0;
}
SOCKET socketClient=socket(AF_INET,SOCK_STREAM,0);
SOCKADDR_IN addrServer;
addrServer.sin_family=AF_INET;
addrServer.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
addrServer.sin_port=htons(6000);
char sendBuf[100];
char recvBuf[100];
printf("客户端向服务器端连接请求...\n");
int Isconnect=connect(socketClient, (struct sockaddr *)&addrServer, sizeof(struct sockaddr));
if(Isconnect!=0)
{
printf("客户端无法连接服务器端...\n");
return 0;
}
printf("客户端已成功连接服务器端...\n");
memset(recvBuf,0,100);
recv(socketClient,recvBuf,100,0);
printf("客户端收到信息:%s\n",recvBuf);
memset(sendBuf,0,100);
sprintf(sendBuf,"Hello , I am Mr Wen !");
send(socketClient, sendBuf, strlen(sendBuf)+1,0);
closesocket(socketClient);
WSACleanup();
return 0;
}
‘叁’ 采用tcp协议,使用socket编程,编写程序完成客户端发送消息给服务端,服务端接到消息后,再发
服务端代码:
/*server.c*/
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <netinet/in.h>
#define PORT 4321
#define BUFFER_SIZE 1024
#define MAX_QUE_CONN_NM 5
int main()
{
struct sockaddr_in server_sockaddr, client_sockaddr;
int sin_size, recvbytes;
int sockfd, client_fd;
char buf[BUFFER_SIZE];
/*建立socket连接*/
if ((sockfd = socket(AF_INET,SOCK_STREAM,0))== -1)
{
perror("socket");
exit(1);
}
printf("Socket id = %d\n",sockfd);
/*设置sockaddr_in 结构体中相关参数*/
server_sockaddr.sin_family = AF_INET;
server_sockaddr.sin_port = htons(PORT);
server_sockaddr.sin_addr.s_addr = INADDR_ANY;
bzero(&(server_sockaddr.sin_zero), 8);
int i = 1;/* 使得重复使用本地地址与套接字进行绑定 */
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i));
/*绑定函数bind*/
if (bind(sockfd, (struct sockaddr *)&server_sockaddr, sizeof(struct sockaddr))== -1)
{
perror("bind");
exit(1);
}
printf("Bind success!\n");
/*调用listen函数*/
if (listen(sockfd, MAX_QUE_CONN_NM) == -1)
{
perror("listen");
exit(1);
}
printf("Listening....\n");
/*调用accept函数,等待客户端的连接*/
if ((client_fd = accept(sockfd, (struct sockaddr *)&client_sockaddr, &sin_size)) == -1)
{
perror("accept");
exit(1);
}
/*调用recv函数接收客户端的请求*/
memset(buf , 0, sizeof(buf));
if ((recvbytes = recv(client_fd, buf, BUFFER_SIZE, 0)) == -1)
{
perror("recv");
exit(1);
}
printf("Received a message: %s\n", buf);
if ((sendbytes = send(sockfd, buf, strlen(buf), 0)) == -1)
{
perror("send");
exit(1);
}
close(sockfd);
exit(0);
}
客户端:
/*client.c*/
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <netdb.h>
#include <netinet/in.h>
#define PORT 4321
#define BUFFER_SIZE 1024
int main(int argc, char *argv[])
{
int sockfd, sendbytes;
char buf[BUFFER_SIZE];
struct hostent *host;
struct sockaddr_in serv_addr;
if(argc < 3)
{
fprintf(stderr,"USAGE: ./client Hostname(or ip address) Text\n");
exit(1);
}
/*地址解析函数*/
if ((host = gethostbyname(argv[1])) == NULL)
{
perror("gethostbyname");
exit(1);
}
memset(buf, 0, sizeof(buf));
sprintf(buf, "%s", argv[2]);
/*创建socket*/
if ((sockfd = socket(AF_INET,SOCK_STREAM,0)) == -1)
{
perror("socket");
exit(1);
}
/*设置sockaddr_in 结构体中相关参数*/
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
serv_addr.sin_addr = *((struct in_addr *)host->h_addr);
bzero(&(serv_addr.sin_zero), 8);
/*调用connect函数主动发起对服务器端的连接*/
if(connect(sockfd,(struct sockaddr *)&serv_addr, sizeof(struct sockaddr))== -1)
{
perror("connect");
exit(1);
}
/*发送消息给服务器端*/
if ((sendbytes = send(sockfd, buf, strlen(buf), 0)) == -1)
{
perror("send");
exit(1);
}
if ((recvbytes = recv(sockfd, buf, BUFFER_SIZE, 0)) == -1)
{
perror("recv");
exit(1);
}
close(sockfd);
exit(0);
}
‘肆’ TCP 和 UDP 在socket编程中的区别
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、关闭网络连接;
‘伍’ socket编程和tcp/ip有什么区别
tcp/ip是通讯协议,三次握手,
socket就是套接字,你可以理解为socket可以使用TCP、IP协议来进行传输数据。
‘陆’ 如何基于TCP/IP协议进行MFC Socket网络通讯编程
可以使用MFC的CAsyncSocket和CSocket类,也可以直接使用Win32 API中的socket系列函数。
‘柒’ mfc中用TCP/IP socket编程来写了一个简单的收发端,可客户端的accept()老连接不上
你的意思是不是服务端卡在accept()那,然后客户端弹出“连接失败!”窗口?
如果是这样的话先检查网络连接是否正常,然后IP是不是对的
如果以上都没问题,用WSAGetLastError()得到错误代码并在MessageBox()中显示。
另外发现你用阻塞方式收发数据,最好将这两段代码放入新线程,否则容易卡死
附上WSAGetLastError()错误代码:
WSAENOTINITIALISED:在使用此API之前应首先成功地调用WSAStartup()。
WSAENETDOWN:WINDOWS套接口实现检测到网络子系统失效。
WSAEADDRINUSE:所指的地址已在使用中。
WSAEINTR:通过一个WSACancelBlockingCall()来取消一个(阻塞的)调用。
WSAEINPROGRESS:一个阻塞的WINDOWS套接口调用正在运行中。
WSAEADDRNOTAVAIL:在本地机器上找不到所指的地址。
WSAENOTSUPPORT:所指族中地址无法与本套接口一起使用。
WSAECONNREFUSED:连接尝试被强制拒绝。
WSAEDESTADDREQ:需要目的地址。
WSAEFAULT:namelen参数不正确。
WSAEINVAL:套接口没有准备好与一地址捆绑。
WSAEISCONN:套接口早已连接。
WSAEMFILE:无多余文件描述字。
WSAENETUNREACH:当前无法从本主机访问网络。
WSAENOBUFS:无可用缓冲区。套接口未被连接。
WSAENOTSOCK:描述字不是一个套接口。
WSAETIMEOUT:超时时间到。
WSAEWOULDBLOCK:套接口设置为非阻塞方式且连接不能立即建立。可用select()调用对套接口写,因为select()时会进行连接。
希望对你有帮肋..
‘捌’ 两台计算机实现TCP(通过socket编程)通信时,要用到线么总感觉仅仅通过代码就能建立连接不太靠谱
TCP连接的基础就是网络连接已经建立好之后,所以物理连接肯定是基础,至于物理连接有很多种,可以是有线的、也可以是无线的,只要协议支持TCP/IP就可以。
‘玖’ 采用tcp协议的socket编程,假如服务器端不知道所要接收的数据的长度,如何定义接收buff的大小
tcp是数据流。
如果你第一次的recv不能接收全部数据,可以再次调用recv接收剩余的。
具体点:
你在发送的时候可以把数据长度写在前4个字节,或者先发送数据长度过来。
接收的时候就能先知道数据长度,再动态分配内存,接收剩余数据。
这是socket中非常常用的方法。
‘拾’ 《JavaTCP/IPSocket编程》epub下载在线阅读,求百度网盘云资源
《Java TCP/IP Socket编程》(Kenneth L. Calvert)电子书网盘下载免费在线阅读
资源链接:
链接:https://pan..com/s/1L6VHTRQySYrO8PdrwEtMmA
书名:Java TCP/IP Socket编程
作者:Kenneth L. Calvert
译者:周恒民
豆瓣评分:8.0
出版社:机械工业出版社
出版年份:2009-1
页数:172
内容简介:
《Java TCP/IP Socket编程(原书第2版)》基于TCP/IP Socket相关原理,对如何在Java中进行Socket编程作了深入浅出的介绍。《Java TCP/IP Socket编程(原书第2版)》内容简明扼要,条理清晰,并在讲解相应的概念或编程技巧时列举了大量的示例程序,每章附有练习。