linux下socket 网络编程(客户端向服务器端发送文件) 求源代码 大哥大姐帮帮忙 。。源码谢谢
server:
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <syslog.h>
#include <sys/time.h>
#include <string.h>
#include <fcntl.h>
#include <sys/wait.h>
#define MAXDATASIZE
#define SERVPORT
#define BACKLOG
int SendFileToServ(const char *path,分析 const char *FileName, const char *ip)
{
#define PORT
int sockfd;
int recvbytes;
char buf[MAXDATASIZE];
char send_str[MAXDATASIZE];
char filepath[] = { 0};
struct sockaddr_in serv_addr;
FILE *fp;
sprintf(filepath, "%s%s", path, FileName);
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
{
perror("socket");
return 1;
}
bzero(&serv_addr,sizeof(struct sockaddr_in));
serv_addr.sin_family=AF_INET;
serv_addr.sin_port=htons(PORT);
inet_aton(ip, &serv_addr.sin_addr);
int IErrCount = 0;
again:
if(connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(struct sockaddr))==-1)
{
if (5 == IErrCount)
return 1;
IErrCount++;
perror("connect");
sleep(2);
goto again;
}
//if ((fp = fopen(FileName, "rb")) == NULL)
if ((fp = fopen(filepath, "rb")) == NULL)
{
perror("fopen ");
return 1;
}
recvbytes = write(sockfd, FileName, strlen(FileName));
recvbytes = read(sockfd, buf, MAXDATASIZE);
if (!memcmp(buf, "sendmsg", 7))
{
while(fgets(send_str, MAXDATASIZE, fp))
{
recvbytes = write(sockfd, send_str, strlen(send_str));
recvbytes = read(sockfd, buf, MAXDATASIZE);
if (recvbytes <= 0)
{
fclose(fp);
close(sockfd);
return 1;
}
if (memcmp(buf, "goon", 4))
{
fclose(fp);
close(sockfd);
return 1;
}
}
recvbytes = write(sockfd, "end", 3);
}
else
{
fclose(fp);
close(sockfd);
return 1;
}
memset(buf, 0, MAXDATASIZE);
if (read(sockfd, buf, MAXDATASIZE) <= 0)
{
close(sockfd);
return 2;
}
char *Eptr = "nginx reload error";
//printf("bf[%s]\n", buf);
int ret;
ret = strncmp(buf, Eptr, strlen(Eptr));
//printf("%d\n", ret);
if (!ret)
{
close(sockfd);
return 2;
}
close(sockfd);
return 0;
}
int mysyslog(const char * msg)
{
FILE *fp;
if ((fp = fopen("/tmp/tmp.log", "a+")) == NULL)
{
return 0;
}
fprintf(fp, "[%s]\n", msg);
fclose(fp);
return 0;
}
static void quit_handler(int signal)
{
kill(0, SIGUSR2);
syslog( LOG_NOTICE, "apuserv quit...");
// do something exit thing ,such as close socket ,close mysql,free list
// .....
//i end
exit(0);
}
static int re_conf = 0;
static void reconf_handler(int signal)
{
re_conf=1;
syslog(LOG_NOTICE,"apuserv reload configure file .");
// 请在循环体中判断,如果re_conf == 1,源码请再次加载配置文件。分析
}
static int isrunning(void)
{
int fd;
int ret;
struct flock lock;
lock.l_type = F_WRLCK;
lock.l_whence = 0;
lock.l_start = 0;
lock.l_len = 0;
const char *lckfile = "/tmp/apuserv.lock";
fd = open(lckfile,源码O_WRONLY|O_CREAT);
if (fd < 0) {
syslog(LOG_ERR,"can not create lock file: %s\n",lckfile);
return 1;
}
if ((ret = fcntl(fd,F_SETLK,&lock)) < 0) {
ret = fcntl(fd,F_GETLK,&lock);
if (lock.l_type != F_UNLCK) {
close(fd);
return lock.l_pid;
}
else {
fcntl(fd,F_SETLK,&lock);
}
}
return 0;
}
int MyHandleBuff(const char *buf, char *str, char *FileName, char *pth)
{
sscanf(buf, "%s %s %s", pth, FileName, str);
printf("path=%s\nfilename=%s\nip=%s\n", pth, FileName, str);
return 0;
}
int main(int argc, char **argv)
{
int sockfd,client_fd;
socklen_t sin_size;
struct sockaddr_in my_addr,remote_addr;
char buff[MAXDATASIZE];
int recvbytes;
#if 1
int pid ;
char ch ;
int ret;
int debug = 0;
signal(SIGUSR1, SIG_IGN);
signal(SIGUSR2, SIG_IGN);
signal(SIGHUP, SIG_IGN);
signal(SIGTERM, quit_handler);
syslog(LOG_NOTICE,"apuserver start....");
while ((ch = getopt(argc, argv, "dhV")) != -1) {
switch (ch) {
case 'd':
debug = 1;
break;
case 'V':
printf("Version:%s\n","1.0.0");
return 0;
case 'h':
printf(" -d use daemon mode\n");
printf(" -V show version\n");
return 0;
default:
printf(" -d use daemon mode\n");
printf(" -V show version\n");
}
}
if (debug && daemon(0,0 ) ) {
return -1;
}
if (isrunning()) {
fprintf(stderr, "apuserv is already running\n");
syslog(LOG_INFO,"apuserv is already running\n");
exit(0);
}
while (1) {
pid = fork();
if (pid < 0)
return -1;
if (pid == 0)
break;
while ((ret = waitpid(pid, NULL, 0)) != pid) {
syslog(LOG_NOTICE, "waitpid want %d, but got %d", pid, ret);
if (ret < 0)
syslog(LOG_NOTICE, "waitpid errno:%d", errno);
}
kill(0, SIGUSR2);
sleep(1);
syslog(LOG_NOTICE,"restart apuserver");
}
signal(SIGHUP, reconf_handler);
signal(SIGPIPE, SIG_IGN);
signal(SIGUSR1,SIG_IGN);
signal(SIGUSR2, SIG_DFL);
signal(SIGTERM, SIG_DFL);
#endif
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
{
perror("socket");
exit(1);
}
bzero(&my_addr,sizeof(struct sockaddr_in));
my_addr.sin_family=AF_INET;
my_addr.sin_port=htons(SERVPORT);
my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
if(bind(sockfd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr))==-1)
{
perror("bind");
exit(1);
}
if(listen(sockfd,BACKLOG)==-1)
{
perror("listen");
exit(1);
}
int nret;
while(1)
{
sin_size = sizeof(struct sockaddr_in);
if((client_fd = accept(sockfd, (struct sockaddr *)&remote_addr, &sin_size))==-1)
{
perror("falied accept");
continue;
}
memset(buff, 0, MAXDATASIZE);
recvbytes = read(client_fd, buff, MAXDATASIZE);
char str[] = { 0};
char FileName[] = { 0};
char path[] = { 0};
MyHandleBuff(buff, str, FileName, path);
if (recvbytes > 0)
{
nret = SendFileToServ(path, FileName, str);
printf("nret[%d]\n", nret);
if (1 == nret)
write(client_fd, "send file error", );
else if(2 == nret)
write(client_fd, "reload nginx error", );
else
write(client_fd, "succ", 4);
}
close(client_fd);
}
}
_________________________________________________
client:
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <syslog.h>
#include <sys/time.h>
#include <string.h>
#include <fcntl.h>
#include <sys/wait.h>
#define MAXDATASIZE
#define SERVPORT
#define BACKLOG
int mysyslog(const char * msg)
{
FILE *fp;
if ((fp = fopen("/tmp/tmp.log", "a+")) == NULL)
{
return 0;
}
fprintf(fp, "[%s]\n", msg);
fclose(fp);
return 0;
}
static void quit_handler(int signal)
{
kill(0, SIGUSR2);
syslog( LOG_NOTICE, "apuserv quit...");
// do something exit thing ,such as close socket ,close mysql,free list
// .....
//i end
exit(0);
}
static int re_conf = 0;
static void reconf_handler(int signal)
{
re_conf=1;
syslog(LOG_NOTICE,"apuserv reload configure file .");
// ·?1nf == 1£?′μ?
static int isrunning(void)
{
int fd;
int ret;
struct flock lock;
lock.l_type = F_WRLCK;
lock.l_whence = 0;
lock.l_start = 0;
lock.l_len = 0;
const char *lckfile = "/tmp/dstserver.lock";
fd = open(lckfile,O_WRONLY|O_CREAT);
if (fd < 0) {
syslog(LOG_ERR,"can not create lock file: %s\n",lckfile);
return 1;
}
if ((ret = fcntl(fd,F_SETLK,&lock)) < 0) {
ret = fcntl(fd,F_GETLK,&lock);
if (lock.l_type != F_UNLCK) {
close(fd);
return lock.l_pid;
}
else {
fcntl(fd,F_SETLK,&lock);
}
}
return 0;
}
int main(int argc, char **argv)
{
int sockfd,client_fd;
socklen_t sin_size;
struct sockaddr_in my_addr,remote_addr;
char buff[MAXDATASIZE];
int recvbytes;
#if 1
int pid ;
char ch ;
int ret;
int debug = 0;
signal(SIGUSR1, SIG_IGN);
signal(SIGUSR2, SIG_IGN);
signal(SIGHUP, SIG_IGN);
signal(SIGTERM, quit_handler);
syslog(LOG_NOTICE,"dstserver start....");
while ((ch = getopt(argc, argv, "dhV")) != -1) {
switch (ch) {
case 'd':
debug = 1;
break;
case 'V':
printf("Version:%s\n","1.0.0");
return 0;
case 'h':
printf(" -d use daemon mode\n");
printf(" -V show version\n");
return 0;
default:
printf(" -d use daemon mode\n");
printf(" -V show version\n");
}
}
if (debug && daemon(0,0 ) ) {
return -1;
}
if (isrunning()) {
fprintf(stderr, "dstserver is already running\n");
syslog(LOG_INFO,"dstserver is already running\n");
exit(0);
}
while (1) {
pid = fork();
if (pid < 0)
return -1;
if (pid == 0)
break;
while ((ret = waitpid(pid, NULL, 0)) != pid) {
syslog(LOG_NOTICE, "waitpid want %d, but got %d", pid, ret);
if (ret < 0)
syslog(LOG_NOTICE, "waitpid errno:%d", errno);
}
kill(0, SIGUSR2);
sleep(1);
syslog(LOG_NOTICE,"restart apuserver");
}
signal(SIGHUP, reconf_handler);
signal(SIGPIPE, SIG_IGN);
signal(SIGUSR1,SIG_IGN);
signal(SIGUSR2, SIG_DFL);
signal(SIGTERM, SIG_DFL);
#endif
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
{
perror("socket");
exit(1);
}
bzero(&my_addr,sizeof(struct sockaddr_in));
my_addr.sin_family=AF_INET;
my_addr.sin_port=htons(SERVPORT);
my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
if(bind(sockfd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr))==-1)
{
perror("bind");
exit(1);
}
if(listen(sockfd,BACKLOG)==-1)
{
perror("listen");
exit(1);
}
char filepath[MAXDATASIZE]= { 0};
FILE *fp;
while(1)
{
sin_size = sizeof(struct sockaddr_in);
if((client_fd = accept(sockfd, (struct sockaddr *)&remote_addr, &sin_size))==-1)
{
perror("falied accept");
continue;
}
memset(buff, 0, MAXDATASIZE);
recvbytes = read(client_fd, buff, MAXDATASIZE);
sprintf(filepath, "/etc/nginx/url_rule/%s", buff);
if ((fp = fopen(filepath, "wb")) == NULL)
{
perror("fopen");
close(client_fd);
continue;
}
write(client_fd, "sendmsg", 7);
while(read(client_fd, buff, MAXDATASIZE))
{
if (!memcmp(buff, "end", 3))
{
fclose(fp);
break;
}
else
{
fprintf(fp, "%s", buff);
write(client_fd, "goon", 4);
}
}
//system("nginx -s reload");
char *Sptr = "nginx reload succ";
char *Eptr = "nginx reload error";
int ret;
ret = system("nginx -s reload");
printf("ret[%d]\n", ret);
if (ret != 0)
{
write(client_fd, Eptr, strlen(Eptr));
}
else
{
write(client_fd, Sptr, strlen(Sptr));
}
close(client_fd);
}
}
以前写的:内容忘记了。不是分析很复杂你可以自己看!
年度Linux6.9内核最新源码解读-网络篇-server端-第一步创建--socket
深入解析年Linux 6.9内核的源码网络篇,从服务端的分析第一步:创建socket开始。理解用户空间与内核空间的源码交互至关重要。当我们在用户程序中调用socket(AF_INET, SOCK_STREAM, 0),实际上是触发了从用户空间到内核空间的系统调用sys_socket(),这是创建网络连接的关键步骤。 首先,让我们关注sys_socket函数。这个函数在net/socket.c文件的位置,无论内核版本如何,都会调用__sys_socket_create函数来实际创建套接字,微博网页版源码它接受地址族、类型、协议和结果指针。创建失败时,会返回错误指针。 在socket创建过程中,参数解析至关重要:网络命名空间(net):隔离网络环境,每个空间有自己的配置,如IP地址和路由。
协议族(family):如IPv4(AF_INET)或IPv6(AF_INET6)。
套接字类型(type):如流式(SOCK_STREAM)或数据报(SOCK_DGRAM)。
协议(protocol):如TCP(IPPROTO_TCP)或UDP(IPPROTO_UDP),默认值自动选择。
结果指针(res):指向新创建的socket结构体。
内核标志(kern):区分用户空间和内核空间的socket。
__sock_create函数处理创建逻辑,调用sock_map_fd映射文件描述符,支持O_CLOEXEC和O_NONBLOCK选项。每个网络协议族有其特有的create函数,如inet_create处理IPv4 TCP创建。 在内核中,安全模块如LSM会通过security_socket_create进行安全检查。macd红二波源码sock_alloc负责内存分配和socket结构初始化,协议族注册和动态加载在必要时进行。RCU机制保护数据一致性,确保在多线程环境中操作的正确性。 理解socket_wq结构体对于异步IO至关重要,它协助socket管理等待队列和通知。例如,在TCP协议族的inet_create函数中,会根据用户请求找到匹配的协议,并设置相关的操作集和数据结构。 通过源码,我们可以看到socket和sock结构体的关系,前者是用户空间操作的抽象,后者是内核处理网络连接的实体。理解这些细节有助于我们更好地编写C++网络程序。 此外,原始套接字(如TCP、UDP和CMP)的应用示例,以及对不同协议的深入理解,如常用的IP协议、专用协议和实验性协议,是怎样安装淘宝客源码进一步学习和实践的重要部分。初学Python,有哪些Pythonic的源码推荐阅读
1. 初学Python时,阅读Pythonic的源码是提高编程技能的有效方法。推荐从Python标准库中关于网络编程的代码开始学习。
2. 首先,深入研究`SocketServer`模块,它为创建服务器提供了基础。同时,学习与之相关的`socket`模块,掌握TCP和UDP编程的基础知识。
3. 接下来,关注`SocketServer`模块中的`ForkingMixIn`和`ThreadingMixIn`类,它们分别展示了forking和threading并发机制的混合使用,这是理解多线程和多进程编程的重要途径。
4. 了解`thread`和`threading`模块,这对于管理并发执行的线程至关重要。
5. 随后,研究`select`模块,它允许你处理I/O多路复用,这是理解操作系统如何高效处理并发I/O操作的关键。
6. 通过学习`select`模块,你将自然过渡到对`selectors`的网页源码浏览器理解,这是Python 3.7引入的更现代的I/O多路复用API。
7. 对于想要深入了解并发编程的初学者,可以学习`asyncore`和`asynchat`模块,它们是异步网络编程的基础。
8. 在网络编程的基础上,如果你的兴趣在于游戏开发或实时应用,可以探索`greenlet`和`gevent`,这些库提供了协程,有助于编写高效的并发代码。
9. 如果你对Web开发感兴趣,从`BaseHTTPServer`、`SimpleHTTPServer`和`CGIHTTPServer`开始你的学习之旅。这些模块可以帮助你理解基本的Web服务器和CGI(Common Gateway Interface)。
. 学习`cgi`和`cgitb`模块,这对于调试和运行CGI脚本非常有用。
. 掌握`cookielib`模块,它处理HTTP cookies,这对于处理用户会话和状态管理至关重要。
. 阅读`wsgiref`模块的源码,它是一个WSGI(Web Server Gateway Interface)参考实现,有助于你理解现代Web框架的工作原理。
. 学习如何编写自己的简单Web框架后,你可以更容易地理解并选择`Flask`、`Web.py`、`Django`或`Pyramid`等流行的Web框架。
. 在进行Web开发时,不可避免地需要与API进行交互。因此,熟悉`httplib`、`urllib`和`urlparse`模块是很重要的,它们帮助你处理HTTP请求和响应。
通过以上步骤,初学者可以逐步建立起对Python网络和Web编程的深刻理解,为进一步的编程之旅打下坚实的基础。
从源码角度分析Tomcat的acceptCount、maxConnections、maxThreads参数
在深入探讨Tomcat的acceptCount、maxConnections和maxThreads参数时,首先理解它们的关键在于理解请求在服务器端的处理流程。acceptCount决定了当所有处理线程忙时,Tomcat能暂存的连接请求队列的最大长度,相当于TCP连接时的全队列容量。maxThreads则是线程池中最大线程数,负责处理实际的HTTP请求。
在连接建立阶段(图1),当客户端尝试连接时,acceptCount在ServerSocket的backlog参数中起作用,它限制了TCP连接队列的大小。接着,初始化的线程池会通过prestartAllCoreThreads启动核心线程,为后续的SocketProcessor做准备。
在Acceptor获取Socket时,serverSocket.accept()的调用受到maxConnections的限制,防止过多的并发连接。一旦获取到Socket,就交由线程池执行SocketProcessor,进行实际的请求处理。
然而,如果处理请求的时间过长,如假设的次请求,需要无限长时间,我们需要考虑线程池的动态管理。如设置acceptCount为,maxThreads为,maxConnections为,minSpareThreads为。这意味着在高并发情况下,即使有个最大连接,acceptCount的个等待队列也足够缓冲,而maxThreads的个线程则负责处理,minSpareThreads则确保了至少有个空闲线程应对突发请求。
总结,acceptCount、maxConnections和maxThreads这三个参数共同影响了Tomcat的并发处理能力和连接队列管理,理解它们在实际应用中的配置和作用至关重要。
Tomcat处理http请求之源码分析 | 京东云技术团队
本文将从请求获取与包装处理、请求传递给 Container、Container 处理请求流程,这 3 部分来讲述一次 http 穿梭之旅。
在 tomcat 组件 Connector 启动时,会监听端口。以 JIoEndpoint 为例,在 Acceptor 类中,socket = serverSocketFactory.acceptSocket (serverSocket); 与客户端建立连接,将连接的 socket 交给 processSocket (socket) 来处理。在 processSocket 中,对 socket 进行包装,交给线程池处理。
线程池中的 SocketProcessor 任务,将 socket 交给 handler 处理,此 handler 为 HttpConnectionHandler 的实例。在 HttpConnectionHandler 的父类 process 方法中,根据请求的状态,创建 HttpProcessor 进行相应的处理,然后切到 HttpProcessor 的父类 AbstractHttpProccessor 中。
在 SocketProcessor 中,从 socket 获取请求数据,进行 keep-alive 处理,数据包装等操作,最终将处理后的请求信息交给了 CoyoteAdapter 的 service 方法。
CoyoteAdapter 的 service 方法中有两个主要任务:一是将 org.apache.coyote.Request 和 org.apache.coyote.Response 转换为继承自 HttpServletRequest 的 org.apache.catalina.connector.Request 和 org.apache.catalina.connector.Response,同时定位到 Context 和 Wrapper。二是将请求交给 StandardEngineValve 处理。
在 postParseRequest 方法中,request 通过 URI 的信息找到属于自己的 Context 和 Wrapper。Mapper 保存了所有的容器信息,初始化时将所有容器添加到了 mapper 中。容器信息的变化由 MapperListener 监听,一旦容器发生变化,MapperListener 将其作为监听者进行处理。
找到请求对应的 Context 和 Wrapper 后,CoyoteAdapter 将包装好的请求交给 Container 处理。从下面的代码片段,我们很容易追踪整个 Container 的调用链,形成时间线图。
最终,StandardWrapperValve 将请求交给 Servlet 处理完成,至此一次 http 请求处理完毕。
怎样指定ServerSocket中的IP 地址
在一台机器里设有多个IP地址时,要ServerSocket只在特定的IP上侦听。1.ServerSocket绑定一个特定IP,在一台机器里运行多个ServerSocket程序,PORT相同源码天空,IP不同。2.ServerSocket绑定多个特定IP,当和CLIENT连接时,能够侦测出CLIENT连接ServerSocket哪个特定IP。----------------------------------------------------------------------------------------------------------------------------------------------------------------不会。IIS的虚拟主机不就可以。不同的IP。一样的PORT。--------------------------------------------------------------------------------我问了一下一个搞VC的,答案是用不着, 一台机器上的serversocket, 会监听本机上所有的IP地址,不用你自己来区分, client请求过来时会自动区分的,如果你想知道具体client连接的是哪个IP地址,可以用getHostbyname(可能是这个函数)获得自己具体的IP.----------------------------------------------------------------------------------------------------------------------------------------------------------------Server 的地址不管它就行了----------------------------------------------------------------------------------------------------------------------------------------------------------------到其它有关ServerSocket的问题去看看即可--------------------------------------------------------------------------------可以吗?我要的是SERVER IP----------------------------------------------------------------------------------------------------------------------------------------------------------------to Another_eYes: 因为他的机器上有多个IP.--------------------------------------------------------------------------------
2024-11-30 12:36
2024-11-30 12:30
2024-11-30 12:28
2024-11-30 12:26
2024-11-30 10:57